Beispiel #1
0
        private void WriteRepoItemProperties(XmlTextWriter xml, RepositoryItemBase ri)
        {
            // Get the properties - need to be ordered so compare/isDirty can work faster
            var properties = ri.GetType().GetMembers().Where(x => x.MemberType == MemberTypes.Property).OrderBy(x => x.Name);  // .OrderBy(x => x.Name);

            foreach (MemberInfo mi in properties)
            {
                object v = null;
                IsSerializedForLocalRepositoryAttribute token = Attribute.GetCustomAttribute(mi, typeof(IsSerializedForLocalRepositoryAttribute), false) as IsSerializedForLocalRepositoryAttribute;
                if (token == null)
                {
                    continue;
                }

                //Get tha attr value
                v = ri.GetType().GetProperty(mi.Name).GetValue(ri);

                // We write the property value only if it is not null and different than default when serialzied
                if (v == null)
                {
                    continue;
                }
                if (IsValueDefault(v, token))
                {
                    continue;
                }


                // Enum might be unknow = not set - so no need to write to xml, like null for object
                if (ri.GetType().GetProperty(mi.Name).PropertyType.IsEnum)
                {
                    string vs = v.ToString();
                    // No need to write enum unknown = null
                    if (vs != "Unknown")
                    {
                        xmlwriteatrr(xml, mi.Name, vs);
                    }
                }
                else
                {
                    if (v != null)
                    {
                        //if (v is RepositoryItem)
                        //{
                        //    xml.WriteStartAttribute(mi.Name);
                        //    // xml.WriteString("Value");
                        //    xmlwriteObject(xml, v);

                        //    xml.WriteWhitespace("\n");
                        //    xml.WriteEndAttribute();

                        //}
                        // else
                        //{
                        xmlwriteatrr(xml, mi.Name, v.ToString());
                        // }
                    }
                }
            }
        }
Beispiel #2
0
        private void xmlwriteHeader(XmlTextWriter xml, RepositoryItemBase repositoryItem)
        {
            // Since Header is simple object and unique, we write the attrs in the order we want
            xml.WriteStartElement(cGingerRepositoryItemHeader);

            if (repositoryItem.RepositoryItemHeader.ItemType == null)
            {
                repositoryItem.RepositoryItemHeader.ItemType = repositoryItem.GetType().Name;
            }

            repositoryItem.RepositoryItemHeader.ItemGuid = repositoryItem.Guid;

            xml.WriteAttributeString(nameof(RepositoryItemHeader.ItemGuid), repositoryItem.RepositoryItemHeader.ItemGuid.ToString());
            xml.WriteAttributeString(nameof(RepositoryItemHeader.ItemType), repositoryItem.RepositoryItemHeader.ItemType);
            xml.WriteAttributeString(nameof(RepositoryItemHeader.CreatedBy), repositoryItem.RepositoryItemHeader.CreatedBy);
            xml.WriteAttributeString(nameof(RepositoryItemHeader.Created), repositoryItem.RepositoryItemHeader.Created.ToString(cDateTimeXMLFormat));

            xml.WriteAttributeString(nameof(RepositoryItemHeader.GingerVersion), repositoryItem.RepositoryItemHeader.GingerVersion.ToString());
            string ver = repositoryItem.RepositoryItemHeader.Version.ToString();

            xml.WriteAttributeString(nameof(RepositoryItemHeader.Version), ver);


            //Why not always?
            if (repositoryItem.RepositoryItemHeader.LastUpdateBy == null)
            {
                repositoryItem.RepositoryItemHeader.LastUpdateBy = Environment.UserName;
            }
            xml.WriteAttributeString("LastUpdateBy", repositoryItem.RepositoryItemHeader.LastUpdateBy.ToString());

            xml.WriteAttributeString(nameof(RepositoryItemHeader.LastUpdate), repositoryItem.RepositoryItemHeader.LastUpdate.ToString(cDateTimeXMLFormat));

            xml.WriteEndElement();
        }
Beispiel #3
0
        public static void ObjectsDeepCopy(RepositoryItemBase sourceObj, RepositoryItemBase targetObj)
        {
            NewRepositorySerializer repoSer = new NewRepositorySerializer();

            string sourceObjXml        = repoSer.SerializeToString(sourceObj);
            NewRepositorySerializer RS = new NewRepositorySerializer();

            RS.DeserializeFromTextWithTargetObj(sourceObj.GetType(), sourceObjXml, targetObj);
        }
Beispiel #4
0
        //TODO: later on get back this function it is more organize, but causing saving problems  -to be fixed later
        private void xmlwriteObject(XmlTextWriter xml, RepositoryItemBase ri)
        {
            string ClassName = ri.GetType().Name;

            xml.WriteStartElement(ClassName);

            WriteRepoItemProperties(xml, ri);
            WriteRepoItemFields(xml, ri);
            xml.WriteEndElement();
        }
Beispiel #5
0
        public void MoveItem(RepositoryItemBase repositoryItem, string targetFolder)
        {
            RepositoryFolderBase RF = GetItemRepositoryFolder(repositoryItem);


            SolutionRepositoryItemInfoBase SRII     = GetSolutionRepositoryItemInfo(repositoryItem.GetType());
            RepositoryFolderBase           rootRF   = SRII.GetItemRepositoryFolder(repositoryItem);
            RepositoryFolderBase           targetRF = rootRF.GetSubFolderByName(targetFolder);



            RF.MoveItem(repositoryItem, targetRF);
        }
Beispiel #6
0
        public bool IsItemTypeHandled(RepositoryItemBase repositoryItem)
        {
            SolutionRepositoryItemInfoBase SRII = null;

            mSolutionRepositoryItemInfoDictionary.TryGetValue(repositoryItem.GetType(), out SRII);
            if (SRII != null)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #7
0
        private void UpdateRepoItemGuids(RepositoryItemBase item, List <GuidMapper> guidMappingList)
        {
            foreach (FieldInfo PI in item.GetType().GetFields())
            {
                var token = PI.GetCustomAttribute(typeof(IsSerializedForLocalRepositoryAttribute));
                if (token == null)
                {
                    continue;
                }

                // we drill down to ObservableList
                if (typeof(IObservableList).IsAssignableFrom(PI.FieldType))
                {
                    IObservableList obj = (IObservableList)PI.GetValue(item);
                    if (obj == null)
                    {
                        return;
                    }
                    List <object> items = ((IObservableList)obj).ListItems;

                    if ((items != null) && (items.Count > 0) && (items[0].GetType().IsSubclassOf(typeof(RepositoryItemBase))))
                    {
                        foreach (RepositoryItemBase ri in items.Cast <RepositoryItemBase>())
                        {
                            GuidMapper mapping = new GuidMapper();
                            mapping.Original = ri.Guid;
                            ri.Guid          = Guid.NewGuid();
                            mapping.newGuid  = ri.Guid;

                            guidMappingList.Add(mapping);

                            UpdateRepoItemGuids(ri, guidMappingList);
                        }
                    }
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Save changes of exsiting Repository Item to file system
        /// </summary>
        /// <param name="repositoryItem"></param>
        public void SaveRepositoryItem(RepositoryItemBase repositoryItem)
        {
            if (String.IsNullOrEmpty(repositoryItem.ContainingFolder))
            {
                throw new Exception("Cannot save item, there is no containing folder defined - " + repositoryItem.GetType().FullName + ", " + repositoryItem.GetNameForFileName());
            }

            repositoryItem.UpdateBeforeSave();

            string txt              = RepositorySerializer.SerializeToString(repositoryItem);
            string filePath         = CreateRepositoryItemFileName(repositoryItem);
            RepositoryFolderBase rf = GetItemRepositoryFolder(repositoryItem);

            rf.SaveRepositoryItem(filePath, txt);
            repositoryItem.FileName = filePath;
            repositoryItem.FilePath = filePath;
            //RI.isDirty = false;  //TODO: make is dirty to work
            SetDirtyStatusToNoChange(repositoryItem);
        }
Beispiel #9
0
        //TODO: fix this method name or cretae or !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        public string CreateRepositoryItemFileName(RepositoryItemBase repositoryItemBase, string containingFolder = "")
        {
            var repositoryItemInfoBaseType = GetSolutionRepositoryItemInfo(repositoryItemBase.GetType());

            string name = repositoryItemBase.ItemName; // (string)RI.GetType().GetProperty(v.PropertyForFileName).GetValue(RI);

            if (repositoryItemBase.FilePath != null && File.Exists(repositoryItemBase.FilePath) && string.IsNullOrEmpty(containingFolder))
            {
                return(repositoryItemBase.FilePath);
            }
            else
            {
                //probably new item so create new path for it

                //FOLDER
                string fileFolderPath = string.Empty;
                if (string.IsNullOrEmpty(containingFolder))
                {
                    fileFolderPath = repositoryItemBase.ContainingFolder;
                }
                else
                {
                    fileFolderPath = containingFolder;
                }

                if (!fileFolderPath.StartsWith(cSolutionRootFolderSign) || !fileFolderPath.StartsWith(mSolutionFolderPath))
                {
                    string solutionPath = mSolutionFolderPath;
                    string filefolder   = fileFolderPath.Replace(cSolutionRootFolderSign, Path.DirectorySeparatorChar.ToString()).TrimStart(Path.DirectorySeparatorChar).TrimEnd(Path.DirectorySeparatorChar);
                    if (!solutionPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
                    {
                        solutionPath += Path.DirectorySeparatorChar;
                    }
                    fileFolderPath = Path.Combine(solutionPath, filefolder);
                    if (fileFolderPath.Length > 260)
                    {
                        ThrowErrorIfPathLimitExeceeded();
                    }
                }

                string fileName = Amdocs.Ginger.Common.GeneralLib.General.RemoveInvalidFileNameChars(name);

                string fullName = repositoryItemInfoBaseType.Pattern.Replace("*", fileName);


                string filefullPath = Path.Combine(fileFolderPath, fullName);

                //TODO: remove max 255 once we switch all to work with .Net core 2.0 no limit
                //Validate Path length - MAX_PATH is 260
                if (filefullPath.Length > 260)
                {
                    var newFileName      = string.Empty;
                    var noOfCharToEscape = 0;
                    if (fileName.Length > 255)
                    {
                        noOfCharToEscape = filefullPath.Length + 2 - 255;
                        newFileName      = fileName.Substring(0, fileName.Length - noOfCharToEscape); //TODO: validate that works as expected using unit test !!!!!!!!!! file extension must remain or give err

                        newFileName  = newFileName + "~1";
                        newFileName  = repositoryItemInfoBaseType.Pattern.Replace("*", newFileName);
                        filefullPath = Path.Combine(fileFolderPath, newFileName);
                    }

                    if (filefullPath.Length > 260 && fileName.Length > 3)
                    {
                        noOfCharToEscape = filefullPath.Length - 257;
                        newFileName      = fileName.Substring(0, fileName.Length - noOfCharToEscape);

                        if (newFileName.Length < 3)
                        {
                            ThrowErrorIfPathLimitExeceeded();
                        }
                        newFileName  = newFileName + "~1";
                        newFileName  = repositoryItemInfoBaseType.Pattern.Replace("*", newFileName);
                        filefullPath = Path.Combine(fileFolderPath, newFileName);
                    }
                    else if (filefullPath.Length > 260 && fileName.Length < 3)
                    {
                        ThrowErrorIfPathLimitExeceeded();
                    }
                }



                //validate no other file with same name

                //find first file which doesn't exist, add ~counter until found
                int    counter = 0;
                string Nameex  = "";
                string ext     = repositoryItemInfoBaseType.Pattern.Replace("*", "");
                while (File.Exists(filefullPath))
                {
                    if (Nameex != "")
                    {
                        filefullPath = filefullPath.Replace(Nameex, "");
                    }
                    counter++;
                    Nameex       = "~" + counter;
                    filefullPath = filefullPath.Replace(ext, Nameex + ext);

                    if (counter > 100)
                    {
                        throw new Exception("cannot find unique file after 100 tries");
                    }
                }

                return(filefullPath);
            }
        }
Beispiel #10
0
        /// <summary>
        /// Get the Repository Folder of the Repository Item
        /// </summary>
        /// <param name="repositoryItem"></param>
        public RepositoryFolderBase GetItemRepositoryFolder(RepositoryItemBase repositoryItem)
        {
            SolutionRepositoryItemInfoBase SRII = GetSolutionRepositoryItemInfo(repositoryItem.GetType());

            return(SRII.GetItemRepositoryFolder(repositoryItem));
        }
Beispiel #11
0
        /// <summary>
        /// Save changes of exsiting Repository Item to file system
        /// </summary>
        /// <param name="repositoryItem"></param>
        public void SaveRepositoryItem(RepositoryItemBase repositoryItem)
        {
            if (String.IsNullOrEmpty(repositoryItem.ContainingFolder))
            {
                throw new Exception("Cannot save item, there is no containing folder defined - " + repositoryItem.GetType().FullName + ", " + repositoryItem.GetNameForFileName());
            }

            repositoryItem.UpdateBeforeSave();

            string txt              = RepositorySerializer.SerializeToString(repositoryItem);
            string filePath         = CreateRepositoryItemFileName(repositoryItem);
            RepositoryFolderBase rf = GetItemRepositoryFolder(repositoryItem);

            rf.SaveRepositoryItem(filePath, txt);
            repositoryItem.FileName = filePath;
            repositoryItem.FilePath = filePath;
            repositoryItem.RefreshSourceControlStatus();
            RefreshParentFoldersSoucerControlStatus(Path.GetDirectoryName(repositoryItem.FilePath));

            if (repositoryItem.DirtyStatus != Common.Enums.eDirtyStatus.NoTracked)
            {
                repositoryItem.SetDirtyStatusToNoChange();
            }
            repositoryItem.CreateBackup();
        }
Beispiel #12
0
        /// <summary>
        /// Save the Repository Item to the Root folder and add it to cache
        /// </summary>
        /// <param name="repositoryItem"></param>
        public void AddRepositoryItem(RepositoryItemBase repositoryItem)
        {
            SolutionRepositoryItemInfoBase SRII = GetSolutionRepositoryItemInfo(repositoryItem.GetType());

            SRII.ItemRootRepositoryFolder.AddRepositoryItem(repositoryItem);
        }
Beispiel #13
0
        private void WriteRepoItemFields(XmlTextWriter xml, RepositoryItemBase ri)
        {
            var Fields = ri.GetType().GetMembers().Where(x => x.MemberType == MemberTypes.Field).OrderBy(x => x.Name);

            foreach (MemberInfo fi in Fields)
            {
                object v = null;
                IsSerializedForLocalRepositoryAttribute token = Attribute.GetCustomAttribute(fi, typeof(IsSerializedForLocalRepositoryAttribute), false) as IsSerializedForLocalRepositoryAttribute;
                if (token == null)
                {
                    continue;
                }

                if (LazyLoadAttr.Contains(fi.Name))
                {
                    bool b = ((IObservableList)(ri.GetType().GetField(fi.Name).GetValue(ri))).LazyLoad;
                    if (b)
                    {
                        // Hurray!
                        string s = ((IObservableList)(ri.GetType().GetField(fi.Name).GetValue(ri))).StringData;
                        xml.WriteStartElement("Activities"); //!!!
                        xml.WriteString(s);
                        xml.WriteEndElement();
                    }
                }

                v = ri.GetType().GetField(fi.Name).GetValue(ri);

                // We write the property value only if it is not null and different than default when serialized
                if (v == null)
                {
                    continue;
                }
                if (IsValueDefault(v, token))
                {
                    continue;
                }

                if (v != null)
                {
                    if (v is IObservableList)
                    {
                        IObservableList vv = (IObservableList)v;
                        if (vv.Count != 0)  // Write only if we have items - save xml space
                        {
                            xmlwriteObservableList(xml, fi.Name, (IObservableList)v);
                        }
                    }
                    else
                    {
                        if (v is List <string> )
                        {
                            xmlwriteStringList(xml, fi.Name, (List <string>)v);
                        }
                        else if (v is RepositoryItemBase)
                        {
                            xmlwriteSingleObjectField(xml, fi.Name, v);
                        }
                        else
                        {
                            //xml.WriteComment(">>>>>>>>>>>>>>>>> Unknown Field type to serialize - " + fi.Name + " - " + v.ToString());
                            throw new Exception("Unknown Field type to serialize - " + fi.Name + " - " + v.ToString());
                        }
                    }
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Save changes of exsiting Repository Item to file system
        /// </summary>
        /// <param name="repositoryItem"></param>
        public void SaveRepositoryItem(RepositoryItemBase repositoryItem)
        {
            if (String.IsNullOrEmpty(repositoryItem.ContainingFolder))
            {
                throw new Exception("Cannot save item, there is no containing folder defined - " + repositoryItem.GetType().FullName + ", " + repositoryItem.GetNameForFileName());
            }

            repositoryItem.UpdateBeforeSave();

            string txt              = RepositorySerializer.SerializeToString(repositoryItem);
            string filePath         = CreateRepositoryItemFileName(repositoryItem);
            RepositoryFolderBase rf = GetItemRepositoryFolder(repositoryItem);

            rf.SaveRepositoryItem(filePath, txt);
            repositoryItem.FileName = filePath;
            repositoryItem.FilePath = filePath;
            //RI.isDirty = false;  //TODO: make is dirty to work
            if (repositoryItem.DirtyStatus == Common.Enums.eDirtyStatus.Modified)
            {
                repositoryItem.DirtyStatus = Common.Enums.eDirtyStatus.NoChange;
            }
            repositoryItem.OnPropertyChanged(nameof(RepositoryItemBase.SourceControlStatus));
        }
Beispiel #15
0
        //TODO: fix this method name or cretae or !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        public string CreateRepositoryItemFileName(RepositoryItemBase RI, string containingFolder = "")
        {
            var v = GetSolutionRepositoryItemInfo(RI.GetType());

            string name = RI.ItemName; // (string)RI.GetType().GetProperty(v.PropertyForFileName).GetValue(RI);

            if (RI.FilePath != null && File.Exists(RI.FilePath) && string.IsNullOrEmpty(containingFolder))
            {
                return(RI.FilePath);
            }
            else
            {
                //probably new item so create new path for it

                //FOLDER
                string fileFolderPath = string.Empty;
                if (string.IsNullOrEmpty(containingFolder))
                {
                    fileFolderPath = RI.ContainingFolder;
                }
                else
                {
                    fileFolderPath = containingFolder;
                }
                if (!fileFolderPath.StartsWith(cSolutionRootFolderSign) || !fileFolderPath.StartsWith(mSolutionFolderPath))
                {
                    // Fix me for Linux !!!
                    string A = mSolutionFolderPath; //.TrimEnd(Path.DirectorySeparatorChar).TrimStart(Path.DirectorySeparatorChar);
                    string B = fileFolderPath.Replace(cSolutionRootFolderSign, Path.DirectorySeparatorChar.ToString()).TrimStart(Path.DirectorySeparatorChar).TrimEnd(Path.DirectorySeparatorChar);
                    A += Path.DirectorySeparatorChar;
                    fileFolderPath = Path.Combine(A, B);
                    Console.WriteLine("fileFolderPath3 =" + fileFolderPath);
                }

                //FILE
                string fileName = name;
                //Removing all possible invalid path chars and checking the file name length is legal (<= 255)
                foreach (char invalidChar in Path.GetInvalidFileNameChars())
                {
                    fileName = fileName.Replace(invalidChar.ToString(), "");
                }
                fileName = fileName.Replace(@".", "");

                string fileExtention = v.Pattern;  //string.Format(".{0}.xml", RI.ObjFileExt);
                string fullName      = v.Pattern.Replace("*", fileName);


                string filefullPath = Path.Combine(fileFolderPath, fullName);

                //TODO: remove max 255 once we swithc all to work with .Net core 2.0 no limit
                //Validate Path length - MAX_PATH is 260
                //if (filefullPath.Length > 255)
                if (fileName.Length > 255)
                {
                    //FIXME !!!!!!!!!!!!!!

                    int    gap     = filefullPath.Length + 2 - 255;
                    string NewName = fileName.Substring(0, fileName.Length - gap);   //TODO: validate that works as expected using unit test !!!!!!!!!! file extension must remain or give err

                    //tODO: throw exception if file name too short...

                    NewName      = NewName + "~1";
                    NewName      = v.Pattern.Replace("*", NewName);
                    filefullPath = Path.Combine(fileFolderPath, NewName);
                }

                //validate no other file with same name

                //find first file which doesn't exist, add ~counter until found
                int    counter = 0;
                string Nameex  = "";
                string ext     = v.Pattern.Replace("*", "");
                while (File.Exists(filefullPath))
                {
                    if (Nameex != "")
                    {
                        filefullPath = filefullPath.Replace(Nameex, "");
                    }
                    counter++;
                    Nameex       = "~" + counter;
                    filefullPath = filefullPath.Replace(ext, Nameex + ext);

                    if (counter > 100)
                    {
                        throw new Exception("cannot find uniqe file after 100 tries");
                    }
                }

                return(filefullPath);
            }
        }
        private RepositoryItemBase CopyRIObject(RepositoryItemBase repoItemToCopy)
        {
            Type objType   = repoItemToCopy.GetType();
            var  targetObj = Activator.CreateInstance(objType) as RepositoryItemBase;

            var objMembers = repoItemToCopy.GetType().GetMembers().Where(x => (x.MemberType == MemberTypes.Property || x.MemberType == MemberTypes.Field));

            repoItemToCopy.PrepareItemToBeCopied();
            targetObj.PreDeserialization();
            Parallel.ForEach(objMembers, mi =>
            {
                try
                {
                    if (IsDoNotBackupAttr(mi))
                    {
                        return;
                    }

                    object memberValue = null;

                    if (mi.MemberType == MemberTypes.Property)
                    {
                        var propInfo = repoItemToCopy.GetType().GetProperty(mi.Name);

                        if (propInfo.CanWrite)
                        {
                            memberValue = propInfo.GetValue(repoItemToCopy);
                            if (memberValue is IObservableList && typeof(IObservableList).IsAssignableFrom(propInfo.PropertyType))
                            {
                                var copiedList = (IObservableList)propInfo.GetValue(targetObj);

                                if (copiedList == null)
                                {
                                    Type listItemType = memberValue.GetType().GetGenericArguments().SingleOrDefault();
                                    var listOfType    = typeof(ObservableList <>).MakeGenericType(listItemType);
                                    copiedList        = (IObservableList)Activator.CreateInstance(listOfType);
                                }

                                CopyRIList((IObservableList)memberValue, copiedList);
                                propInfo.SetValue(targetObj, copiedList);
                            }
                            else
                            {
                                propInfo.SetValue(targetObj, memberValue);
                            }
                        }
                    }
                    else
                    {
                        FieldInfo fieldInfo = repoItemToCopy.GetType().GetField(mi.Name);
                        memberValue         = fieldInfo.GetValue(repoItemToCopy);
                        fieldInfo.SetValue(targetObj, memberValue);
                    }
                }
                catch (Exception ex)
                {
                    Reporter.ToLog(eLogLevel.ERROR, string.Format("Error occured during object copy of the item: '{0}', type: '{1}', property/field: '{2}'", this.ItemName, this.GetType(), mi.Name), ex);
                }
            });

            targetObj.PostDeserialization();
            targetObj.UpdateCopiedItem();

            return(targetObj);
        }
        //TODO: fix this method name or cretae or !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        public string CreateRepositoryItemFileName(RepositoryItemBase RI, string containingFolder = "")
        {
            var v = GetSolutionRepositoryItemInfo(RI.GetType());

            string name = RI.ItemName; // (string)RI.GetType().GetProperty(v.PropertyForFileName).GetValue(RI);

            if (RI.FilePath != null && File.Exists(RI.FilePath) && string.IsNullOrEmpty(containingFolder))
            {
                return(RI.FilePath);
            }
            else
            {
                //probably new item so create new path for it

                //FOLDER
                string fileFolderPath = string.Empty;
                if (string.IsNullOrEmpty(containingFolder))
                {
                    fileFolderPath = RI.ContainingFolder;
                }
                else
                {
                    fileFolderPath = containingFolder;
                }
                if (!fileFolderPath.StartsWith(cSolutionRootFolderSign) || !fileFolderPath.StartsWith(mSolutionFolderPath))
                {
                    string A = mSolutionFolderPath;
                    string B = fileFolderPath.Replace(cSolutionRootFolderSign, Path.DirectorySeparatorChar.ToString()).TrimStart(Path.DirectorySeparatorChar).TrimEnd(Path.DirectorySeparatorChar);
                    if (!A.EndsWith(Path.DirectorySeparatorChar.ToString()))
                    {
                        A += Path.DirectorySeparatorChar;
                    }
                    fileFolderPath = Path.Combine(A, B);
                }

                string fileName = Amdocs.Ginger.Common.GeneralLib.General.RemoveInvalidFileNameChars(name);

                string fullName = v.Pattern.Replace("*", fileName);


                string filefullPath = Path.Combine(fileFolderPath, fullName);

                //TODO: remove max 255 once we switch all to work with .Net core 2.0 no limit
                //Validate Path length - MAX_PATH is 260
                if (fileName.Length > 255)
                {
                    //FIXME !!!!!!!!!!!!!!

                    int    gap     = filefullPath.Length + 2 - 255;
                    string NewName = fileName.Substring(0, fileName.Length - gap);   //TODO: validate that works as expected using unit test !!!!!!!!!! file extension must remain or give err

                    //tODO: throw exception if file name too short...

                    NewName      = NewName + "~1";
                    NewName      = v.Pattern.Replace("*", NewName);
                    filefullPath = Path.Combine(fileFolderPath, NewName);
                }

                //validate no other file with same name

                //find first file which doesn't exist, add ~counter until found
                int    counter = 0;
                string Nameex  = "";
                string ext     = v.Pattern.Replace("*", "");
                while (File.Exists(filefullPath))
                {
                    if (Nameex != "")
                    {
                        filefullPath = filefullPath.Replace(Nameex, "");
                    }
                    counter++;
                    Nameex       = "~" + counter;
                    filefullPath = filefullPath.Replace(ext, Nameex + ext);

                    if (counter > 100)
                    {
                        throw new Exception("cannot find unique file after 100 tries");
                    }
                }

                return(filefullPath);
            }
        }