private void RemoveInvalidFiles(IDomainObjectDTORepository repoDto, DomainObjectDTO langProj, DomainObjectDTO folder) { var langProjElement = XElement.Parse(langProj.Xml); var pictures = langProjElement.Element("Pictures"); var fileMap = CreateFilePathToGuidMap(repoDto, folder); var pictureMap = CreateFileGuidToPictureMap(repoDto); foreach (var x in pictures.Elements()) { var xObj = repoDto.GetDTO(x.Attribute("guid").Value); if (xObj.Classname == "CmFile") { string replacementFileGuid; string filePath = GetFilePath(xObj); if (filePath != null && fileMap.TryGetValue(filePath.ToLowerInvariant(), out replacementFileGuid)) { UpdatePictureReferences(repoDto, xObj, replacementFileGuid, pictureMap); DataMigrationServices.RemoveIncludingOwnedObjects(repoDto, xObj, true); } else if (!pictureMap.ContainsKey(xObj.Guid)) { DataMigrationServices.RemoveIncludingOwnedObjects(repoDto, xObj, true); } else { MoveFileToFolder(repoDto, folder, xObj); RemoveReferenceFromPictures(repoDto, langProj, xObj.Guid); } } } }
/// <summary> /// Creates a CmPossibility with all the basic properties filled in for the xml (necessary for S/R) and adds it to the dto /// </summary> public static DomainObjectDTO CreatePossibility(IDomainObjectDTORepository repoDto, string listGuid, string possibilityGuid, string name, string abbr, DateTime createTime, string className = "CmPossibility") { var sb = new StringBuilder(); sb.AppendFormat("<rt class=\"{0}\" guid=\"{1}\" ownerguid=\"{2}\">", className, possibilityGuid, listGuid); sb.Append("<Abbreviation>"); sb.AppendFormat("<AUni ws=\"en\">{0}</AUni>", abbr); sb.Append("</Abbreviation>"); sb.Append(string.Format("<DateCreated val=\"{0:yyyy-MM-dd HH:mm:ss.fff}\" />", createTime)); sb.Append(string.Format("<DateModified val=\"{0:yyyy-MM-dd HH:mm:ss.fff}\" />", createTime)); sb.Append("<BackColor val=\"-1073741824\" />"); sb.Append("<ForeColor val=\"-1073741824\" />"); sb.Append("<IsProtected val=\"True\" />"); sb.Append("<Hidden val=\"False\" />"); sb.Append("<Name>"); sb.AppendFormat("<AUni ws=\"en\">{0}</AUni>", name); sb.Append("</Name>"); sb.Append("<SortSpec val=\"-1073741824\" />"); sb.Append("<UnderColor val=\"-1073741824\" />"); sb.Append("<UnderStyle val=\"-1073741824\" />"); sb.Append("</rt>"); var dtoCmPossibility = new DomainObjectDTO(possibilityGuid, className, sb.ToString()); repoDto.Add(dtoCmPossibility); return(dtoCmPossibility); }
/// <summary> /// Given that the element has been changed to represent the desired new state of some DTO, /// save the change. This overload finds the DTO from the guid attribute on the element. /// </summary> private void UpdateDto(IDomainObjectDTORepository domainObjectDtoRepository, XElement element) { DomainObjectDTO dto = domainObjectDtoRepository.GetDTO(element.Attribute("guid").Value); dto.Xml = element.ToString(); domainObjectDtoRepository.Update(dto); }
public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository) { DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000050); var newGuidValue = Guid.NewGuid().ToString().ToLowerInvariant(); const string className = "LangProject"; var lpDto = domainObjectDtoRepository.AllInstancesSansSubclasses(className).First(); var ownedDtos = domainObjectDtoRepository.GetDirectlyOwnedDTOs(lpDto.Guid).ToList(); var data = lpDto.Xml; domainObjectDtoRepository.Remove(lpDto); // It is pretty hard to change an immutable Guid identifier in BEP-land, so nuke it, and make a new one. var lpElement = XElement.Parse(data); lpElement.Attribute("guid").Value = newGuidValue; var newLpDto = new DomainObjectDTO(newGuidValue, className, lpElement.ToString()); domainObjectDtoRepository.Add(newLpDto); // Change ownerguid attr for each owned item to new guid. foreach (var ownedDto in ownedDtos) { var ownedElement = XElement.Parse(ownedDto.Xml); ownedElement.Attribute("ownerguid").Value = newGuidValue; ownedDto.Xml = ownedElement.ToString(); domainObjectDtoRepository.Update(ownedDto); } DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository); }
private void AddToClassList(DomainObjectDTO dto) { var className = dto.Classname; string superclassName; if (!m_classAndSuperClass.TryGetValue(className, out superclassName)) { // Can't determine old superclass, without going through the DTO's xml. m_classAndSuperClass.Add(className, null); // Discovering old direct subclasses may not be possible. m_classesAndTheirDirectSubclasses.Add(className, new HashSet <string>()); } if (superclassName == null) { // Unknown class, so must be obsolete. m_oldTimers.Add(dto); } HashSet <DomainObjectDTO> instances; if (!m_dtosByClass.TryGetValue(className, out instances)) { instances = new HashSet <DomainObjectDTO>(); m_dtosByClass.Add(className, instances); } instances.Add(dto); }
public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository) { DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000050); var newGuidValue = Guid.NewGuid().ToString().ToLowerInvariant(); const string className = "LangProject"; var lpDto = domainObjectDtoRepository.AllInstancesSansSubclasses(className).First(); var ownedDtos = domainObjectDtoRepository.GetDirectlyOwnedDTOs(lpDto.Guid).ToList(); var data = lpDto.Xml; domainObjectDtoRepository.Remove(lpDto); // It is pretty hard to change an immutable Guid identifier in BEP-land, so nuke it, and make a new one. var lpElement = XElement.Parse(data); lpElement.Attribute("guid").Value = newGuidValue; var newLpDto = new DomainObjectDTO(newGuidValue, className, lpElement.ToString()); domainObjectDtoRepository.Add(newLpDto); // Change ownerguid attr for each owned item to new guid. foreach (var ownedDto in ownedDtos) { var ownedElement = XElement.Parse(ownedDto.Xml); ownedElement.Attribute("ownerguid").Value = newGuidValue; ownedDto.Xml = ownedElement.ToString(); domainObjectDtoRepository.Update(ownedDto); } DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository); }
/// <summary> /// Add to weatherItems the guids of all the things owned directly or indirectly by dtoRoot. /// Does not include the root itself. /// </summary> private void CollectItems(IDomainObjectDTORepository repoDTO, DomainObjectDTO dtoRoot, HashSet <string> guidCollector) { foreach (var dto in repoDTO.GetDirectlyOwnedDTOs(dtoRoot.Guid)) { guidCollector.Add(dto.Guid); CollectItems(repoDTO, dto, guidCollector); } }
/// <summary> /// The weather list is used, so convert it to a custom (unowned) list, create a new /// custom field for RnGenericRec elements, and convert any Weather elements to that /// new custom field. /// </summary> private void ConvertWeatherToCustomListAndField(IDomainObjectDTORepository repoDTO) { // Change the Weather list to being unowned. DomainObjectDTO dtoLP = null; foreach (var dto in repoDTO.AllInstancesWithSubclasses("LangProject")) { dtoLP = dto; break; } string sWeatherListGuid = RemoveWeatherConditionsElement(dtoLP).ToLowerInvariant(); repoDTO.Update(dtoLP); DomainObjectDTO dtoWeatherList = null; foreach (var dto in repoDTO.AllInstancesWithSubclasses("CmPossibilityList")) { if (dto.Guid.ToLowerInvariant() == sWeatherListGuid) { dtoWeatherList = dto; break; } } dtoWeatherList.Xml = RemoveOwnerGuid(dtoWeatherList.Xml); repoDTO.Update(dtoWeatherList); // Create the custom field. string fieldName = "Weather"; while (repoDTO.IsFieldNameUsed("RnGenericRec", fieldName)) { fieldName = fieldName + "A"; } repoDTO.CreateCustomField("RnGenericRec", fieldName, SIL.CoreImpl.CellarPropertyType.ReferenceCollection, CmPossibilityTags.kClassId, "originally a standard part of Data Notebook records", WritingSystemServices.kwsAnals, new Guid(sWeatherListGuid)); string customStart = String.Format("<Custom name=\"{0}\">", fieldName); // Remove any empty Weather elements in the RnGenericRec objects, and convert // nonempty ones to custom elements. foreach (var dto in repoDTO.AllInstancesWithSubclasses("RnGenericRec")) { string sXml = dto.Xml; int idx = sXml.IndexOf("<Weather"); if (idx > 0) { string sXmlT = RemoveEmptyWeather(sXml, idx); if (sXmlT == sXml) { sXmlT = sXml.Replace("<Weather>", customStart); sXmlT = sXmlT.Replace("</Weather>", "</Custom>"); } dto.Xml = sXmlT; repoDTO.Update(dto); } } }
private void GatherDeadObjects(IDomainObjectDTORepository repoDTO, DomainObjectDTO dtoDead, List <DomainObjectDTO> rgdtoDead) { rgdtoDead.Add(dtoDead); foreach (var dto in repoDTO.GetDirectlyOwnedDTOs(dtoDead.Guid)) { GatherDeadObjects(repoDTO, dto, rgdtoDead); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Removes the specified field. /// </summary> /// <param name="dto">The domain transfer object that has a field that may need to be deleted.</param> /// <param name="objElement">Name of the object containing fieldToDelete.</param> /// <param name="fieldToDelete">The name of the field to delete.</param> /// ------------------------------------------------------------------------------------ private void RemoveField(DomainObjectDTO dto, XElement objElement, string fieldToDelete) { XElement rmElement = objElement.Element(fieldToDelete); if (rmElement != null) { rmElement.Remove(); } }
private void RemoveFromClassList(DomainObjectDTO obj, string oldClassName) { HashSet <DomainObjectDTO> instances; if (m_dtosByClass.TryGetValue(oldClassName, out instances)) { instances.Remove(obj); } }
internal static void CheckDtoRemoved(IDomainObjectDTORepository dtoRepos, DomainObjectDTO goner) { DomainObjectDTO dto; if (dtoRepos.TryGetValue(goner.Guid, out dto)) { Assert.Fail("Still has deleted (or zombie) DTO."); } Assert.IsTrue(((DomainObjectDtoRepository)dtoRepos).Goners.Contains(goner)); }
public void DataMigration7000009Test() { var dtos = new HashSet<DomainObjectDTO>(); var sb = new StringBuilder(); // 1. Add barebones LP. sb.Append("<rt class=\"LangProject\" guid=\"9719A466-2240-4DEA-9722-9FE0746A30A6\">"); sb.Append("<LangProject>"); sb.Append("<Texts>"); var lpTextsGuids = new StTextAndParaInfo("9719A466-2240-4DEA-9722-9FE0746A30A6", "Normal"); sb.Append("<objsur guid=\"" + lpTextsGuids.textGuid + "\" t=\"o\" />"); sb.Append("</Texts>"); sb.Append("<TranslatedScripture>"); sb.Append("<objsur guid=\"2c5c1f5f-1f08-41d7-99fe-23893ee4ceef\" t=\"o\" />"); sb.Append("</TranslatedScripture>"); sb.Append("</LangProject>"); sb.Append("</rt>"); var expectedLp = sb.ToString(); var lpDto = new DomainObjectDTO("9719A466-2240-4DEA-9722-9FE0746A30A6", "LangProject", expectedLp); dtos.Add(lpDto); // 2. Add Scripture sb = new StringBuilder(); sb.Append( "<rt class=\"Scripture\" guid=\"2c5c1f5f-1f08-41d7-99fe-23893ee4ceef\" ownerguid=\"9719A466-2240-4DEA-9722-9FE0746A30A6\""); int index = sb.Length; sb.Append(">"); sb.Append("<Scripture>"); sb.Append("<Books>"); sb.Append("<objsur guid=\"f213db11-7007-4a2f-9b94-06d6c96014ca\" t=\"o\" />"); sb.Append("</Books>"); sb.Append("</Scripture>"); sb.Append("</rt>"); string expected = sb.ToString(); sb.Insert(index, " owningflid=\"6001040\" owningord=\"0\""); var scrDto = new DomainObjectDTO("2c5c1f5f-1f08-41d7-99fe-23893ee4ceef", "Scripture", sb.ToString()); dtos.Add(scrDto); // Set up mock MDC. var mockMDC = new MockMDCForDataMigration(); mockMDC.AddClass(1, "CmObject", null, new List<string> { "LangProject", "Scripture" }); mockMDC.AddClass(2, "LangProject", "CmObject", new List<string>()); mockMDC.AddClass(4, "Scripture", "CmObject", new List<string>()); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000008, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000009, new DummyProgressDlg()); Assert.AreEqual(expected, scrDto.Xml); Assert.AreEqual(expectedLp, lpDto.Xml); Assert.AreEqual(7000009, dtoRepos.CurrentModelVersion, "Wrong updated version."); }
private void RemoveUnwantedOverlays(IDomainObjectDTORepository repoDTO, List <DomainObjectDTO> collectOverlaysToRemove) { DomainObjectDTO dtoLP = GetDtoLangProj(repoDTO); foreach (var dto in collectOverlaysToRemove) { RemoveOverlayElement(dtoLP, dto.Guid); repoDTO.Remove(dto); } }
/// <summary> /// Rest the xml in the DTO and register the DTO as udated with the repository. /// Use this overload only if the class name is NOT changing. /// </summary> /// <remarks> /// There is no validation of the xml, other than making sure it is not null, /// or an emty string. /// </remarks> internal static void UpdateDTO(IDomainObjectDTORepository dtoRepos, DomainObjectDTO dirtball, string newXmlValue) { if (dtoRepos == null) throw new ArgumentNullException("dtoRepos"); if (dirtball == null) throw new ArgumentNullException("dirtball"); if (String.IsNullOrEmpty(newXmlValue)) throw new ArgumentNullException("newXmlValue"); dirtball.Xml = newXmlValue; dtoRepos.Update(dirtball); }
/// <summary> /// Rest the xml in the DTO and register the DTO as udated with the repository. /// Use this overload only if the class name is NOT changing. /// </summary> /// <remarks> /// There is no validation of the xml, other than making sure it is not null, /// or an emty string. /// </remarks> internal static void UpdateDTO(IDomainObjectDTORepository dtoRepos, DomainObjectDTO dirtball, byte[] newXmlBytes) { if (dtoRepos == null) throw new ArgumentNullException("dtoRepos"); if (dirtball == null) throw new ArgumentNullException("dirtball"); if (newXmlBytes == null || newXmlBytes.Length == 0) throw new ArgumentNullException("newXmlBytes"); dirtball.XmlBytes = newXmlBytes; dtoRepos.Update(dirtball); }
void ChangeClassOfOwnerAndChildren(IDomainObjectDTORepository dtoRepo, DomainObjectDTO dtoToChange, string oldClassname, string newClassname) { // bail out if we've already changed the class name (assume we've already changed its children too). if (!TryChangeOwnerClass(dtoRepo, dtoToChange, oldClassname, newClassname)) return; foreach (var dtoChild in dtoRepo.GetDirectlyOwnedDTOs(dtoToChange.Guid)) { ChangeClassOfOwnerAndChildren(dtoRepo, dtoChild, oldClassname, newClassname); } }
private DomainObjectDTO GetDtoLangProj(IDomainObjectDTORepository repoDTO) { DomainObjectDTO dtoLP = null; foreach (var dto in repoDTO.AllInstancesWithSubclasses("LangProject")) { dtoLP = dto; break; } return(dtoLP); }
public void DataMigration7000056Test() { var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000056.xml"); // Set up mock MDC. var mockMDC = new MockMDCForDataMigration(); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000055, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000056, new DummyProgressDlg()); Assert.AreEqual(7000056, dtoRepos.CurrentModelVersion, "Wrong updated version."); // check that PhPhonData has the PhonRuleFeats possibility list { var dtosList = dtoRepos.AllInstancesSansSubclasses("PhPhonData"); DomainObjectDTO dtoPhPhonDataTest = dtosList.First(); CheckPhPhonData(dtoPhPhonDataTest, dtoRepos); } // In the extremely unlikely event that there is no PhPhonData yet, check that we add it { dtos = new HashSet<DomainObjectDTO>(); var sb = new StringBuilder(); // Add WfiMorphBundle that already has a form. const string sGuid_wmbLangProj = "00b35f9f-86ce-4f07-bde7-b65c28503641"; sb.AppendFormat("<rt class=\"LangProj\" guid=\"{0}\">", sGuid_wmbLangProj); sb.Append("</rt>"); var dtoLangProj = new DomainObjectDTO(sGuid_wmbLangProj, "LangProj", sb.ToString()); dtos.Add(dtoLangProj); sb.Length = 0; mockMDC = new MockMDCForDataMigration(); dtoRepos = new DomainObjectDtoRepository(7000055, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000056, new DummyProgressDlg()); Assert.AreEqual(7000056, dtoRepos.CurrentModelVersion, "Wrong updated version."); var dtosList = dtoRepos.AllInstancesSansSubclasses("LangProj"); DomainObjectDTO dtoLangProjTest = dtosList.First(); var eltWmbLangProjTest = XElement.Parse(dtoLangProjTest.Xml); // get phon rule feats var eltPhonologicalDataTest = eltWmbLangProjTest.Element("PhonologicalData"); Assert.IsNotNull(eltPhonologicalDataTest); var eltObjsurTest = eltPhonologicalDataTest.Element("objsur"); Assert.IsNotNull(eltObjsurTest); // get possibility list itself var guidPhPhonDataTest = eltObjsurTest.Attribute("guid").Value; Assert.IsNotNull(guidPhPhonDataTest); DomainObjectDTO dtoPhPhonDataTest; dtoRepos.TryGetValue(guidPhPhonDataTest, out dtoPhPhonDataTest); Assert.IsNotNull(dtoPhPhonDataTest); CheckPhPhonData(dtoPhPhonDataTest, dtoRepos); } }
/// <summary> /// Does two components of changing the class of a DTO representation of the object: /// Fixes the class attribute, and fixes the Classname of the DTO. /// Caller should arrange to move it from one list to another, and fix the /// embedded elements (see e.g. ChangeToSubClass). /// </summary> /// <param name="target"></param> /// <param name="oldClass"></param> /// <param name="newClass"></param> private static void ChangeClass(DomainObjectDTO target, string oldClass, string newClass) { // If there's no unexpected white space we can do this efficiently. // This depends (like various other code) on NOT having unexpected white space around the '='. byte[] classBytes = Encoding.UTF8.GetBytes("class=\"" + oldClass + "\""); int index = target.XmlBytes.IndexOfSubArray(classBytes); byte[] newClassBytes = Encoding.UTF8.GetBytes("class=\"" + newClass + "\""); target.XmlBytes = target.XmlBytes.ReplaceSubArray(index, classBytes.Length, newClassBytes); target.Classname = newClass; }
private void VerifyAnalysis(DomainObjectDTO analysis, string[] evaluations) { var rtElement = XElement.Parse(analysis.Xml); var agentElt = rtElement.Element("WfiAnalysis"); var evaluationsElt = agentElt.Element("Evaluations"); Assert.IsNotNull(evaluationsElt); Assert.AreEqual(evaluations.Length, evaluationsElt.Elements().Count()); var wanted = new HashSet<string>(evaluations); foreach (var objsur in evaluationsElt.Elements()) VerifyReference(objsur, wanted); }
private string RemoveWeatherConditionsElement(DomainObjectDTO dtoLP) { string sLpXml = dtoLP.Xml; int idx = sLpXml.IndexOf("<WeatherConditions>"); int idxEnd = sLpXml.IndexOf("</WeatherConditions>"); int cch = (idxEnd + 20) - idx; string sWeatherConditions = sLpXml.Substring(idx, cch); dtoLP.Xml = sLpXml.Remove(idx, cch); return(ExtractFirstGuid(sWeatherConditions, 0, " guid=\"")); }
private string GetFilePath(DomainObjectDTO file) { var fileElement = XElement.Parse(file.Xml); var pathElement = fileElement.Element("InternalPath"); if (pathElement != null) { pathElement = pathElement.Element("Uni"); } return(pathElement != null ? pathElement.Value : null); }
private static void GetWsNamesFromReversalIndex(DomainObjectDTO revIndexDto, Dictionary <string, string> wsCodeNameDict) { var wsElt = XElement.Parse(revIndexDto.Xml).Element(Name); var existingNameAUniElts = wsElt.Elements(Auni); foreach (var aUniElt in existingNameAUniElts) { var wsCode = aUniElt.Attribute("ws").Value; var wsUiStr = aUniElt.Value; wsCodeNameDict.Add(wsCode, wsUiStr); } }
void ChangeClassOfOwnerAndChildren(IDomainObjectDTORepository dtoRepo, DomainObjectDTO dtoToChange, string oldClassname, string newClassname) { // bail out if we've already changed the class name (assume we've already changed its children too). if (!TryChangeOwnerClass(dtoRepo, dtoToChange, oldClassname, newClassname)) { return; } foreach (var dtoChild in dtoRepo.GetDirectlyOwnedDTOs(dtoToChange.Guid)) { ChangeClassOfOwnerAndChildren(dtoRepo, dtoChild, oldClassname, newClassname); } }
private bool IsWeatherUsed(IDomainObjectDTORepository repoDTO, List <DomainObjectDTO> collectOverlaysToRemove) { DomainObjectDTO dtoLP = GetDtoLangProj(repoDTO); string sLpXml = dtoLP.Xml; int idxW = sLpXml.IndexOf("<WeatherConditions>"); var sguidWeather = ExtractFirstGuid(sLpXml, idxW, " guid=\""); DomainObjectDTO dtoWeather = repoDTO.GetDTO(sguidWeather); var weatherItems = new HashSet <string>(); CollectItems(repoDTO, dtoWeather, weatherItems); foreach (var dto in repoDTO.AllInstancesWithSubclasses("RnGenericRec")) { string sXml = dto.Xml; int idx = sXml.IndexOf("<Weather>"); if (idx > 0) { int idxEnd = sXml.IndexOf("</Weather>"); if (idxEnd > idx) { string s = sXml.Substring(idx, idxEnd - idx); if (s.Contains("<objsur ")) { return(true); } } } bool dummy = false; if (StringContainsRefToItemInList("PhraseTags", weatherItems, sXml, ref dummy)) { return(true); } } foreach (var dto in repoDTO.AllInstancesSansSubclasses("CmOverlay")) { string sXml = dto.Xml; bool hasOtherItems = false; bool hasWeatherRef = StringContainsRefToItemInList("PossItems", weatherItems, sXml, ref hasOtherItems); var weatherListSet = new HashSet <string>(); weatherListSet.Add(sguidWeather.ToLowerInvariant()); hasWeatherRef |= StringContainsRefToItemInList("PossList", weatherListSet, sXml, ref hasOtherItems); if (hasWeatherRef) { if (hasOtherItems) { return(true); // an overlay with a mixture of weather and non-weather items is a problem } // One with only weather refs (and not used, since we know nothing is tagged to weather) // will be deleted. collectOverlaysToRemove.Add(dto); } } return(false); }
/// <summary> /// Remove a 'deleted' <see cref="DomainObjectDTO"/> from the repository. /// /// The deletion of the underlying CmObject object won't happen, /// until the entire current migration is finished. /// </summary> /// <param name="goner">The object being deleted.</param> void IDomainObjectDTORepository.Remove(DomainObjectDTO goner) { if (goner == null) { throw new ArgumentNullException("goner"); } m_goners.Add(goner); m_dtoByGuid.Remove(goner.Guid.ToLower()); m_dtos.Remove(goner); RemoveFromClassList(goner); }
bool TryChangeOwnerClass(IDomainObjectDTORepository dtoRepo, DomainObjectDTO dtoToChange, string oldClassname, string newClassname) { XElement dtoToChangeElt = XElement.Parse(dtoToChange.Xml); if (dtoToChangeElt.Attribute("class").Value != oldClassname) return false; dtoToChangeElt.Attribute("class").Value = newClassname; dtoToChange.Classname = newClassname; // next go through all the children of these known system variant types and change all of their children's classes. DataMigrationServices.UpdateDTO(dtoRepo, dtoToChange, dtoToChangeElt.ToString(), oldClassname); return true; }
/// <summary> /// Let the Repository know that <paramref name="dirtball"/> has been modified. /// </summary> /// <param name="dirtball">The object that was modified.</param> /// <remarks> /// The underlying CmObject won't be changed, until the end of the current /// migration is finished. /// </remarks> void IDomainObjectDTORepository.Update(DomainObjectDTO dirtball) { if (dirtball == null) { throw new ArgumentNullException("dirtball"); } if (!m_dtoByGuid.ContainsKey(dirtball.Guid.ToLower())) { throw new InvalidOperationException("Can't update DTO that isn't in the system."); } m_dirtballs.Add(dirtball); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Get the owner <see cref="DomainObjectDTO"/> for the specified object. /// </summary> /// <param name="ownedObj">The owned <see cref="DomainObjectDTO"/>.</param> /// <returns> /// The owner <see cref="DomainObjectDTO"/> for the given <paramref name="ownedObj"/>, /// or null, if there is no owner. /// </returns> /// <exception cref="ArgumentException"> /// Thrown if the owned object is not in the repository. /// </exception> /// ------------------------------------------------------------------------------------ DomainObjectDTO IDomainObjectDTORepository.GetOwningDTO(DomainObjectDTO ownedObj) { if (ownedObj == null) { throw new ArgumentNullException("ownedObj"); } var ownIdx = ownedObj.XmlBytes.IndexOfSubArray(OwnerGuid); return((ownIdx < 0) ? null : AsInterface.GetDTO(Encoding.UTF8.GetString(ownedObj.XmlBytes.SubArray(ownIdx + 11, 36)))); }
private static void UpdateObjSurElement(IDomainObjectDTORepository dtoRepos, DomainObjectDTO dto, string oldGuid, string newGuid) { var rtElem = XElement.Parse(dto.Xml); var ownObjSurGuidAttr = (from objSurNode in rtElem.Descendants("objsur") where objSurNode.Attribute("guid").Value.ToLower() == oldGuid.ToLower() select objSurNode.Attribute("guid")).FirstOrDefault(); // Ought not be null, but play it safe. if (ownObjSurGuidAttr != null) { ownObjSurGuidAttr.Value = newGuid; } UpdateDTO(dtoRepos, dto, rtElem.ToString()); }
private static void VerifyObject(DomainObjectDTO dto, IEnumerable<string> oldClassElements, ICollection<string> expectedPropertyElements) { // Make sure the old class elements are gone. var rtElement = XElement.Parse(dto.Xml); foreach (var oldClassElement in oldClassElements) Assert.IsNull(rtElement.Element(oldClassElement)); // Make sure the prop elements are child elements of <rt> element. var propElements = rtElement.Elements(); Assert.AreEqual(expectedPropertyElements.Count, propElements.Count(), "Wrong number of property child elements."); foreach (var propElement in propElements) Assert.IsTrue(expectedPropertyElements.Contains(propElement.Name.LocalName)); }
/// <summary> /// Add a new <see cref="DomainObjectDTO"/> to the repository. /// </summary> /// <param name="newby">The new object to add.</param> void IDomainObjectDTORepository.Add(DomainObjectDTO newby) { if (newby == null) { throw new ArgumentNullException("newby"); } // Will throw an exception, if it is already present, // which is just fine. m_dtoByGuid.Add(newby.Guid.ToLower(), newby); m_dtos.Add(newby); AddToClassList(newby); m_newbies.Add(newby); }
private void RemoveReferenceFromPictures(IDomainObjectDTORepository repoDto, DomainObjectDTO langProj, string guid) { var langProjElement = XElement.Parse(langProj.Xml); foreach (var x in langProjElement.Element("Pictures").Elements()) { if (x.Attribute("guid").Value == guid) { x.Remove(); break; } } DataMigrationServices.UpdateDTO(repoDto, langProj, langProjElement.ToString()); }
bool TryChangeOwnerClass(IDomainObjectDTORepository dtoRepo, DomainObjectDTO dtoToChange, string oldClassname, string newClassname) { XElement dtoToChangeElt = XElement.Parse(dtoToChange.Xml); if (dtoToChangeElt.Attribute("class").Value != oldClassname) { return(false); } dtoToChangeElt.Attribute("class").Value = newClassname; dtoToChange.Classname = newClassname; // next go through all the children of these known system variant types and change all of their children's classes. DataMigrationServices.UpdateDTO(dtoRepo, dtoToChange, dtoToChangeElt.ToString(), oldClassname); return(true); }
private void MoveFileToFolder(IDomainObjectDTORepository repoDto, DomainObjectDTO folder, DomainObjectDTO fileToMove) { // Create surogate for file and add it to the folder var surrogate = DataMigrationServices.CreateOwningObjSurElement(fileToMove.Guid); var folderElement = XElement.Parse(folder.Xml); var filesElement = folderElement.Element("Files"); filesElement.Add(surrogate); DataMigrationServices.UpdateDTO(repoDto, folder, folderElement.ToString()); // Change owner of file var fileElement = XElement.Parse(fileToMove.Xml); fileElement.Attribute("ownerguid").SetValue(folder.Guid); DataMigrationServices.UpdateDTO(repoDto, fileToMove, fileElement.ToString()); }
// Make a new CmFile element for the specified path, and an objsur child of langCmFolder to own it. // In this migration a typical result would be: // <rt guid="c4f4760e-049e-49af-ac57-73c686100700" class="CmFile" ownerguid="3e615e09-3b86-4fae-adfe-5fc2473214b6"> // <InternalPath> // <Uni>C:\FwWW\DistFiles\AudioVisual\NotInLinkedFilesPath.WMV</Uni> // </InternalPath> // </rt> private void MakeCmFile(IDomainObjectDTORepository domainObjectDtoRepository, string langCmFolderGuid, XElement langCmFolder, string path) { string cmFileGuid; cmFileGuid = Guid.NewGuid().ToString(); var cmFileXElement = new XElement("rt", new XAttribute("guid", cmFileGuid), new XAttribute("class", "CmFile"), new XAttribute("ownerguid", langCmFolderGuid), MakeUnicode("InternalPath", path)); var dtoConfirmed = new DomainObjectDTO(cmFileGuid, "CmFile", cmFileXElement.ToString()); domainObjectDtoRepository.Add(dtoConfirmed); langCmFolder.Element("Files").Add(MakeOwningSurrogate(cmFileGuid)); }
private void UpdatePictureReferences(IDomainObjectDTORepository repoDto, DomainObjectDTO file, string replacementFileGuid, Dictionary <string, List <DomainObjectDTO> > pictureMap) { List <DomainObjectDTO> pictures; if (pictureMap.TryGetValue(file.Guid, out pictures)) { foreach (var picture in pictures) { var pictureElement = XElement.Parse(picture.Xml); var objSurrogateElement = pictureElement.Element("PictureFile").Element("objsur"); objSurrogateElement.Attribute("guid").Value = replacementFileGuid; DataMigrationServices.UpdateDTO(repoDto, picture, pictureElement.ToString()); } } }
private static DomainObjectDTO MakeEvaluation(string ownerGuid, IDomainObjectDTORepository domainObjectDtoRepository, XElement agentElement, string owningAttr) { var newGuid = Guid.NewGuid().ToString().ToLower(); var newEvalElt = new XElement("rt", new XAttribute("class", "CmAgentEvaluation"), new XAttribute("guid", newGuid), new XAttribute("ownerguid", ownerGuid), new XElement("CmObject"), new XElement("CmAgentEvaluation")); // Create new dto and add to repos. var newEval = new DomainObjectDTO(newGuid, "CmAgentEvaluation", newEvalElt.ToString()); domainObjectDtoRepository.Add(newEval); agentElement.Add(new XElement(owningAttr, new XElement("objsur", new XAttribute("t", "o"), new XAttribute("guid", newGuid)))); return newEval; }
/// <summary> /// Change class of object to a new subclass of the original class. /// Caller still needs to move it from one collection to another in the repository. /// </summary> internal static void ChangeToSubClass(DomainObjectDTO target, string oldClass, string newClass) { ChangeClass(target, oldClass, newClass); // Need to fill in the new empty element. It will be right before the closing <\rt>. byte[] input = target.XmlBytes; int index = input.Length - ClosingRt.Length; for (int i = 0; i < ClosingRt.Length; i++) { if (input[i + index] != ClosingRt[i]) { index = input.IndexOfSubArray(ClosingRt); } } byte[] insertBytes = Encoding.UTF8.GetBytes("<" + newClass + "/>"); target.XmlBytes = input.ReplaceSubArray(index, 0, insertBytes); }
public void DataMigration7000051Test() { var dtos = new HashSet<DomainObjectDTO>(); var sb = new StringBuilder(); // Add Lang Project dto. const string sLpGuid = "9719A466-2240-4DEA-9722-9FE0746A30A6"; const string afxCatGuid = "60ab6c6c-43f3-4a7f-af61-96b4b77648a5"; sb.AppendFormat("<rt class=\"LangProject\" guid=\"{0}\">", sLpGuid); sb.Append("<AffixCategories>"); sb.AppendFormat("<objsur guid=\"{0}\" t=\"o\" />", afxCatGuid); sb.Append("</AffixCategories>"); sb.Append("</rt>"); var oldDto = new DomainObjectDTO(sLpGuid, "LangProject", sb.ToString()); dtos.Add(oldDto); sb.Length = 0; sb.AppendFormat("<rt class=\"CmPossibilityList\" guid=\"{0}\" ownerguid=\"{1}\" />", afxCatGuid, sLpGuid); var afxCatDto = new DomainObjectDTO(afxCatGuid, "CmPossibilityList", sb.ToString()); dtos.Add(afxCatDto); // Set up mock MDC. var mockMDC = new MockMDCForDataMigration(); mockMDC.AddClass(1, "CmObject", null, new List<string> { "LangProject", "CmPossibilityList" }); // Not true, but no matter. mockMDC.AddClass(2, "LangProject", "CmObject", new List<string>()); mockMDC.AddClass(3, "CmPossibilityList", "CmObject", new List<string>()); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000050, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000051, new DummyProgressDlg()); Assert.AreEqual(7000051, dtoRepos.CurrentModelVersion, "Wrong updated version."); // Check that the old LP is not present. DomainObjectDTO gonerDto; Assert.IsFalse(dtoRepos.TryGetValue(sLpGuid, out gonerDto)); Assert.IsTrue(((DomainObjectDtoRepository)dtoRepos).Goners.Contains(oldDto)); var newDto = dtoRepos.AllInstancesSansSubclasses("LangProject").FirstOrDefault(); Assert.IsNotNull(newDto); Assert.AreNotSame(oldDto, newDto); var newDtoGuid = newDto.Guid.ToLowerInvariant(); Assert.AreNotEqual(sLpGuid.ToLowerInvariant(), newDtoGuid); // Check that ownerguid was changed on afxCatDto. var afxCatElm = XElement.Parse(afxCatDto.Xml); Assert.AreEqual(newDtoGuid, afxCatElm.Attribute("ownerguid").Value.ToLowerInvariant()); }
private static void CheckPhPhonData(DomainObjectDTO dtoPhPhonDataTest, IDomainObjectDTORepository dtoRepos) { var eltWmbPhPhonDataTest = XElement.Parse(dtoPhPhonDataTest.Xml); // get phon rule feats var eltPhonRuleFeatsTest = eltWmbPhPhonDataTest.Element("PhonRuleFeats"); Assert.IsNotNull(eltPhonRuleFeatsTest); var eltObjsurTest = eltPhonRuleFeatsTest.Element("objsur"); Assert.IsNotNull(eltObjsurTest); // get possibility list itself var guidPossibilityListTest = eltObjsurTest.Attribute("guid").Value; Assert.IsNotNull(guidPossibilityListTest); DomainObjectDTO dtoCmPossiblityTest; dtoRepos.TryGetValue(guidPossibilityListTest, out dtoCmPossiblityTest); Assert.IsNotNull(dtoCmPossiblityTest); var eltWmbCmPossibilityListTest = XElement.Parse(dtoCmPossiblityTest.Xml); Assert.IsNotNull(eltWmbCmPossibilityListTest); var attrCmPossiblityListClassTest = eltWmbCmPossibilityListTest.Attribute("class").Value; Assert.AreEqual("CmPossibilityList", attrCmPossiblityListClassTest); var attrCmPossiblityListOwnerGuidTest = eltWmbCmPossibilityListTest.Attribute("ownerguid").Value; Assert.AreEqual(dtoPhPhonDataTest.Guid, attrCmPossiblityListOwnerGuidTest); }
static private void AddGlossAppendIfEmpty(IDomainObjectDTORepository dtoRepo, DomainObjectDTO dtoToChange, string glossAppend) { XElement dtoToChangeElt = XElement.Parse(dtoToChange.Xml); XElement glossAppendElt = dtoToChangeElt.XPathSelectElement("GlossAppend"); if (glossAppendElt == null) { dtoToChangeElt.Add(XElement.Parse("<GlossAppend/>")); glossAppendElt = dtoToChangeElt.XPathSelectElement("GlossAppend"); } XElement aUniElt = glossAppendElt.XPathSelectElement("AUni[@ws='en']"); if (aUniElt == null) { glossAppendElt.Add(XElement.Parse("<AUni ws='en'/>")); aUniElt = glossAppendElt.XPathSelectElement("AUni[@ws='en']"); } if (aUniElt.Value.Trim().Length == 0) { aUniElt.Value = glossAppend; } DataMigrationServices.UpdateDTO(dtoRepo, dtoToChange, dtoToChangeElt.ToString()); }
private void FixOrAddMissingTypes(IDomainObjectDTORepository repoDto, IEnumerable<LexTypeInfo> extraTypes) { foreach (var info in extraTypes) { var fChanged = false; foreach (var xeAUni in info.XmlElement.XPathSelectElements("Name/AUni")) { var xaWs = xeAUni.Attribute("ws"); if (xaWs == null || xaWs.Value.ToLowerInvariant() != "en") continue; var name = xeAUni.Value; string guidStd; if (!m_mapNameGuid.TryGetValue(name, out guidStd)) continue; // We need to change the guid of this dto from 'guid to 'guidStd ChangeInvalidGuid(repoDto, info, name, guidStd); } var xeProt = info.XmlElement.XPathSelectElement("IsProtected"); if (xeProt == null) { info.XmlElement.Add(new XElement("IsProtected", new XAttribute("val", "true"))); fChanged = true; } else { var xaVal = xeProt.Attribute("val"); if (xaVal == null) { xeProt.Add(new XAttribute("val", "true")); fChanged = true; } else if (xaVal.Value.ToLowerInvariant() != "true") { xaVal.SetValue("true"); fChanged = true; } } if (fChanged) { info.DTO.Xml = info.XmlElement.ToString(); repoDto.Update(info.DTO); } } if (m_mapNameGuid.Count > 0) { BuildNewTypeMaps(); var newTypes = new HashSet<DomainObjectDTO>(); foreach (var guid in m_mapGuidName.Keys) { // We need to create this LexEntryType! var rgNewDtos = m_mapGuidNewDtos[guid]; foreach (var info in rgNewDtos) { var dto = new DomainObjectDTO(info.Guid, info.ClassName, info.Xml); repoDto.Add(dto); if (info.ClassName == "LexEntryType") newTypes.Add(dto); } } foreach (var dto in newTypes) { var dtoOwner = repoDto.GetOwningDTO(dto); var xeOwner = XElement.Parse(dtoOwner.Xml); XElement xePoss = null; if (dtoOwner.Classname == "CmPossibilityList") { xePoss = xeOwner.Element("Possibilities"); if (xePoss == null) { xePoss = new XElement("Possibilities"); xeOwner.Add(xePoss); } } else if (dtoOwner.Classname == "LexEntryType") { xePoss = xeOwner.Element("SubPossibilities"); if (xePoss == null) { xePoss = new XElement("SubPossibilities"); xeOwner.Add(xePoss); } } if (xePoss != null) { var fNeeded = true; foreach (var objsur in xePoss.Elements("objsur")) { var xaGuid = objsur.Attribute("guid"); if (xaGuid == null) throw new Exception("missing guid in an objsur element"); if (xaGuid.Value.Equals(dto.Guid, StringComparison.OrdinalIgnoreCase)) { fNeeded = false; break; } } if (fNeeded) { xePoss.Add(DataMigrationServices.CreateOwningObjSurElement(dto.Guid)); dtoOwner.Xml = xeOwner.ToString(); repoDto.Update(dtoOwner); } } } } }
public void DataMigration7000001_and_Delint_Tests() { var dtos = new HashSet<DomainObjectDTO>(); // 1. Add barebones LP. // LP will have one extra property to make sure it isnt; affected. // LP will also have a couple 'dangling' references for when 'Delint' is tested. // LP will also have an empty Name element that ought to be removed. var xml = string.Format("<rt class=\"LangProject\" guid=\"9719A466-2240-4DEA-9722-9FE0746A30A6\">{0}" + "<CmObject></CmObject>{0}" + "<LangProject>{0}" + "<Name>{0}" + "</Name>{0}" + "<FakeBoolProperty val=\"True\" />{0}" + "<FakeProperty>bogus content</FakeProperty>{0}" + "<EthnologueCode>{0}" + "<Uni>ZPI</Uni>{0}" + "</EthnologueCode>{0}" + "<WordformInventory>{0}" + "<objsur guid=\"6C84F84A-5B99-4CF5-A7D5-A308DDC604E0\" t=\"o\"/>{0}" + "</WordformInventory>{0}" + "<AnalysisStatus>{0}" + "<objsur guid=\"44AF225F-964C-4F7B-BE51-1AE05995D38C\" t=\"o\" />{0}" + "</AnalysisStatus>{0}" + "<CurVernWss>{0}" + "<objsur guid=\"D75F7FB5-BABD-4D60-B57F-E188BEF264B7\" t=\"r\"/>{0}" + "</CurVernWss>{0}" + "</LangProject>{0}" + "</rt>", Environment.NewLine); var lpDto = new DomainObjectDTO("9719A466-2240-4DEA-9722-9FE0746A30A6", "LangProject", xml); dtos.Add(lpDto); xml = string.Format( "<rt class=\"WordformInventory\" guid=\"6C84F84A-5B99-4CF5-A7D5-A308DDC604E0\" ownerguid=\"9719A466-2240-4DEA-9722-9FE0746A30A6\" owningflid=\"6001013\" owningord=\"1\">{0}" + "<CmObject></CmObject>{0}" + "<WordformInventory>{0}" + "<Wordforms>{0}" + "<objsur guid=\"88304983-CDB2-460B-B3D5-5F95C66F27FF\" t=\"o\" />{0}" + "<objsur guid=\"59821DAB-AB03-470E-B430-5696A0503A08\" t=\"o\" />{0}" + "</Wordforms>{0}" + "</WordformInventory>{0}" + "</rt>", Environment.NewLine); var wfiDto = new DomainObjectDTO("6C84F84A-5B99-4CF5-A7D5-A308DDC604E0", "WordformInventory", xml); dtos.Add(wfiDto); // 3. Add two wordforms // First wordform. xml = string.Format( "<rt class=\"WfiWordform\" guid=\"88304983-CDB2-460B-B3D5-5F95C66F27FF\" ownerguid=\"6C84F84A-5B99-4CF5-A7D5-A308DDC604E0\" owningflid=\"5063001\" owningord=\"1\">{0}" + "<CmObject></CmObject>{0}" + "<WfiWordform>{0}" + "<Checksum val=\"1722980789\"/>{0}" + "<Form>{0}" + "<AUni ws=\"eZPI\">aerekondixyonada</AUni>{0}" + "</Form>{0}" + "<SpellingStatus val=\"1\"/>{0}" + "</WfiWordform>{0}" + "</rt>", Environment.NewLine); var wf1Dto = new DomainObjectDTO("88304983-CDB2-460B-B3D5-5F95C66F27FF", "WfiWordform", xml); dtos.Add(wf1Dto); // Second wordform. xml = string.Format( "<rt class=\"WfiWordform\" guid=\"59821DAB-AB03-470E-B430-5696A0503A08\" ownerguid=\"6C84F84A-5B99-4CF5-A7D5-A308DDC604E0\" owningflid=\"5063001\" owningord=\"2\">{0}" + "<CmObject></CmObject>{0}" + "<WfiWordform>{0}" + "<Checksum val=\"-1933028922\"/>{0}" + "<Form>{0}" + "<AUni ws=\"eZPI\">aeropwerto</AUni>{0}" + "</Form>{0}" + "<SpellingStatus val=\"1\"/>{0}" + "</WfiWordform>{0}" + "</rt>", Environment.NewLine); var wf2Dto = new DomainObjectDTO("59821DAB-AB03-470E-B430-5696A0503A08", "WfiWordform", xml); dtos.Add(wf2Dto); // Add zombie, which is where an object's owner does not exist. xml = @"<rt class=""LexSense"" guid=""3462BE3E-4817-4BBE-B2B9-30828B48E2C7"" ownerguid=""0875E978-79C5-4F87-95FE-A4235C0711C1"" owningflid=""5002011"" owningord=""1"" />"; var zombie = new DomainObjectDTO("3462BE3E-4817-4BBE-B2B9-30828B48E2C7", "LexSense", xml); dtos.Add(zombie); // Add another zombie, // which is where an object's owner *does* exist, // but it doesn't know it owns the zombie. xml = @"<rt class=""Text"" guid=""c1ecaa72-e382-11de-8a39-0800200c9a66"" ownerguid=""9719A466-2240-4DEA-9722-9FE0746A30A6"" owningflid=""6001006"" owningord=""1"" />"; var zombie2 = new DomainObjectDTO("c1ecaa72-e382-11de-8a39-0800200c9a66", "Text", xml); dtos.Add(zombie2); // Set up mock MDC. var mockMDC = new MockMDCForDataMigration(); mockMDC.AddClass(1, "CmObject", null, new List<string> { "LangProject", "Text", "WfiWordform", "LexSense" }); mockMDC.AddClass(2, "LangProject", "CmObject", new List<string>()); mockMDC.AddClass(3, "Text", "CmObject", new List<string>()); mockMDC.AddClass(4, "WfiWordform", "CmObject", new List<string>()); mockMDC.AddClass(5, "LexSense", "CmObject", new List<string>()); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000000, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000001, new DummyProgressDlg()); // Make sure version number is correct. Assert.AreEqual(7000001, dtoRepos.CurrentModelVersion, "Wrong updated version."); // Make sure <rt class=\"LangProject\" ...> has no WFI property. var lpElement = XElement.Parse(lpDto.Xml); var lpInnerLpElement = lpElement.Element("LangProject"); Assert.IsNotNull(lpInnerLpElement, "Oops. The 'LangProject' node was also eaten :-(."); Assert.IsNull(lpInnerLpElement.Element("WordformInventory"), "Still has WFI in the LangProj element."); // Sanity checks. Assert.IsNotNull(lpInnerLpElement.Element("EthnologueCode"), "Oops. The 'EthnologueCode' was also eaten :-(."); // Make sure there is no WordformInventory <rt> element DataMigrationTestServices.CheckDtoRemoved(dtoRepos, wfiDto); // Make sure the two wordforms have no owning-related attrs. var wfRtElements = new List<XElement> { XElement.Parse(wf1Dto.Xml), XElement.Parse(wf2Dto.Xml) }; foreach (var wfElement in wfRtElements) { Assert.IsNull(wfElement.Attribute("ownerguid"), "Still has 'ownerguid'attr."); Assert.IsNull(wfElement.Attribute("owningflid"), "Still has 'owningflid'attr."); Assert.IsNull(wfElement.Attribute("owningord"), "Still has 'owningord'attr."); // Sanity checks. Assert.IsNotNull(wfElement.Descendants("WfiWordform").FirstOrDefault(), "Oops. The 'WfiWordform' element was also eaten :-(."); Assert.IsNotNull(wfElement.Descendants("Checksum").FirstOrDefault(), "Oops. The 'Checksum' element was also eaten :-(."); } // [NB: Other unit tests need not check Delint, as once is good enough. :-)] // Make sure Delint worked. // Make sure dangling owned object was removed. var analStatusElement = lpElement.Descendants("AnalysisStatus").FirstOrDefault(); Assert.IsNull(analStatusElement, "Now empty element was not removed."); // Make sure dangling regular reference was removed. var curVernWssElement = lpElement.Descendants("CurVernWss").FirstOrDefault(); Assert.IsNull(curVernWssElement, "Now empty element was not removed."); // Make sure zombie was removed. DataMigrationTestServices.CheckDtoRemoved(dtoRepos, zombie); // Make sure zombie2 was removed. DataMigrationTestServices.CheckDtoRemoved(dtoRepos, zombie2); // Make sure Delint handled emtpy properties correctly. Assert.IsNull(lpInnerLpElement.Element("Name"), "Empty 'Name' property not removed."); Assert.IsNotNull(lpInnerLpElement.Element("FakeBoolProperty"), "Oops. 'FakeBoolProperty' removed."); Assert.IsNull(lpInnerLpElement.Element("FakeProperty"), "'FakeProperty' survived."); }
/// <summary> /// Reset the xml in the DTO and register the DTO as updated with the repository. /// Use this overload if the class name is changing. /// </summary> /// <remarks> /// There is no validation of the xml, other than making sure it is not null, /// or an emty string. /// </remarks> internal static void UpdateDTO(IDomainObjectDTORepository dtoRepos, DomainObjectDTO dirtball, string newXmlValue, string oldClassName) { dtoRepos.ChangeClass(dirtball, oldClassName); UpdateDTO(dtoRepos, dirtball, newXmlValue); }
private static void UpdateStringsAndProps(IDomainObjectDTORepository domainObjectDtoRepository, DomainObjectDTO dto, HashSet<string> referencedWsIds) { XElement objElem = XElement.Parse(dto.Xml); bool modified = false; foreach (XElement elem in objElem.Descendants()) { switch (elem.Name.LocalName) { case "Run": case "AStr": case "AUni": if (UpdateWsAttribute(elem, referencedWsIds)) modified = true; break; case "BulNumFontInfo": case "Prop": case "WsProp": if (UpdateWsAttribute(elem, referencedWsIds)) modified = true; if (UpdateFontAttribute(elem)) modified = true; break; } } if (modified) DataMigrationServices.UpdateDTO(domainObjectDtoRepository, dto, objElem.ToString()); }
private static DomainObjectDTO MakeEvaluation(string ownerGuid, IDomainObjectDTORepository domainObjectDtoRepository, XElement agentElement, string owningAttr) { var newGuid = Guid.NewGuid().ToString().ToLower(); var newEvalElt = new XElement("rt", new XAttribute("class", "CmAgentEvaluation"), new XAttribute("guid", newGuid), new XAttribute("ownerguid", ownerGuid), new XElement("CmObject"), new XElement("CmAgentEvaluation")); // Create new dto and add to repos. var newEval = new DomainObjectDTO(newGuid, "CmAgentEvaluation", newEvalElt.ToString()); domainObjectDtoRepository.Add(newEval); agentElement.Add(new XElement(owningAttr, new XElement("objsur", new XAttribute("t", "o"), new XAttribute("guid", newGuid)))); return newEval; }
internal LexTypeInfo(DomainObjectDTO dto, XElement xe) { DTO = dto; XmlElement = xe; }
/// <summary> /// Changes the GUID of the specified DTO. It updates the owner and all specified referrers to point to the new GUID. /// </summary> /// <param name="dtoRepos">The dto repos.</param> /// <param name="dto">The dto.</param> /// <param name="newGuid">The new GUID.</param> /// <param name="possibleReferrers">The possible referrers.</param> internal static void ChangeGuid(IDomainObjectDTORepository dtoRepos, DomainObjectDTO dto, string newGuid, IEnumerable<DomainObjectDTO> possibleReferrers) { // if the DTO already has the new GUID, don't do anything if (dto.Guid.ToLowerInvariant() == newGuid.ToLowerInvariant()) return; XElement rtElem = XElement.Parse(dto.Xml); rtElem.Attribute("guid").Value = newGuid; dtoRepos.Add(new DomainObjectDTO(newGuid, dto.Classname, rtElem.ToString())); foreach (DomainObjectDTO ownedDto in dtoRepos.GetDirectlyOwnedDTOs(dto.Guid)) { XElement ownedElem = XElement.Parse(ownedDto.Xml); ownedElem.Attribute("ownerguid").Value = newGuid; UpdateDTO(dtoRepos, ownedDto, ownedElem.ToString()); } var ownerDto = dtoRepos.GetOwningDTO(dto); if (ownerDto != null) UpdateObjSurElement(dtoRepos, ownerDto, dto.Guid, newGuid); if (possibleReferrers != null) { foreach (DomainObjectDTO referrer in possibleReferrers) UpdateObjSurElement(dtoRepos, referrer, dto.Guid, newGuid); } dtoRepos.Remove(dto); }
/// <summary> /// Remove <paramref name="goner"/> and everything it owns. /// Be sure to include removing goner from its optional owning property. /// </summary> internal static void RemoveIncludingOwnedObjects(IDomainObjectDTORepository dtoRepos, DomainObjectDTO goner, bool removeFromOwner) { DomainObjectDTO gonerActual; if (!dtoRepos.TryGetValue(goner.Guid, out gonerActual)) return; // Not in repos. if (removeFromOwner) { var ownerDto = dtoRepos.GetOwningDTO(goner); if (ownerDto != null) { var ownerElement = XElement.Parse(ownerDto.Xml); var ownObjSurElement = (from objSurNode in ownerElement.Descendants("objsur") where objSurNode.Attribute("t").Value == "o" && objSurNode.Attribute("guid").Value.ToLower() == goner.Guid.ToLower() select objSurNode).FirstOrDefault(); // Ought not be null, but play it safe. if (ownObjSurElement != null) ownObjSurElement.Remove(); if (!RemoveEmptyPropertyElements(dtoRepos, ownerDto, ownerElement)) { // No empty property elements removed, so we have to do the update. UpdateDTO(dtoRepos, ownerDto, ownerElement.ToString()); } } } foreach (var ownedDto in dtoRepos.GetDirectlyOwnedDTOs(goner.Guid)) RemoveIncludingOwnedObjects(dtoRepos, ownedDto, false); dtoRepos.Remove(goner); }
/// <summary> /// Change class of object to a new subclass of the original class. /// Caller still needs to move it from one collection to another in the repository. /// </summary> internal static void ChangeToSubClass(DomainObjectDTO target, string oldClass, string newClass) { ChangeClass(target, oldClass, newClass); // Need to fill in the new empty element. It will be right before the closing <\rt>. byte[] input = target.XmlBytes; int index = input.Length - ClosingRt.Length; for (int i = 0; i < ClosingRt.Length; i++) if (input[i + index] != ClosingRt[i]) { index = input.IndexOfSubArray(ClosingRt); } byte[] insertBytes = Encoding.UTF8.GetBytes("<" + newClass + "/>"); target.XmlBytes = input.ReplaceSubArray(index, 0, insertBytes); }
private static string[] ExtractReferencedObjects(DomainObjectDTO dto) { var rootElement = XElement.Parse(dto.Xml); return (from objSurElement in rootElement.Descendants("objsur") select objSurElement.Attribute("guid").Value).ToArray(); }
/// <summary> /// Does two components of changing the class of a DTO representation of the object: /// Fixes the class attribute, and fixes the Classname of the DTO. /// Caller should arrange to move it from one list to another, and fix the /// embedded elements (see e.g. ChangeToSubClass). /// </summary> /// <param name="target"></param> /// <param name="oldClass"></param> /// <param name="newClass"></param> private static void ChangeClass(DomainObjectDTO target, string oldClass, string newClass) { // If there's no unexpected white space we can do this efficiently. // This depends (like various other code) on NOT having unexpected white space around the '='. byte[] classBytes = Encoding.UTF8.GetBytes("class=\"" + oldClass + "\""); int index = target.XmlBytes.IndexOfSubArray(classBytes); byte[] newClassBytes = Encoding.UTF8.GetBytes("class=\"" + newClass + "\""); target.XmlBytes = target.XmlBytes.ReplaceSubArray(index, classBytes.Length, newClassBytes); target.Classname = newClass; }
private static bool RemoveEmptyPropertyElements(IDomainObjectDTORepository dtoRepos, DomainObjectDTO currentDto, XContainer rtElement) { var propertyElements = (rtElement.Element("CmObject") != null) ? rtElement.Elements().Elements() // Two levels for old stuff before DM15 : rtElement.Elements(); // ToArray is required or Remove will end loop early. var emptyPropertyElements = (propertyElements.Where(propertyElement => !propertyElement.HasAttributes && !propertyElement.HasElements)).ToArray(); foreach (var emptyPropertyElement in emptyPropertyElements) { emptyPropertyElement.Remove(); } // Notify of update, if it changed. var results = false; if (emptyPropertyElements.Any()) { UpdateDTO(dtoRepos, currentDto, rtElement.ToString()); results = true; } return results; }
/// <summary> /// Remove a number of objects with a common owner, and everything they own. /// </summary> internal static void RemoveMultipleIncludingOwnedObjects(IDomainObjectDTORepository dtoRepos, List<DomainObjectDTO> goners, DomainObjectDTO ownerDto) { if (ownerDto != null) { var ownerElement = XElement.Parse(ownerDto.Xml); foreach (var goner in goners) { var goner1 = goner; var ownObjSurElement = (from objSurNode in ownerElement.Descendants("objsur") where objSurNode.Attribute("t").Value == "o" && objSurNode.Attribute("guid").Value.ToLower() == goner1.Guid.ToLower() select objSurNode).FirstOrDefault(); // Ought not be null, but play it safe. if (ownObjSurElement != null) ownObjSurElement.Remove(); } if (!RemoveEmptyPropertyElements(dtoRepos, ownerDto, ownerElement)) { // No empty property elememtns removed, so we have to do the update. UpdateDTO(dtoRepos, ownerDto, ownerElement.ToString()); } } foreach (var goner in goners) { foreach (var ownedDto in dtoRepos.GetDirectlyOwnedDTOs(goner.Guid)) RemoveIncludingOwnedObjects(dtoRepos, ownedDto, false); dtoRepos.Remove(goner); } }
/// <summary> /// /// </summary> /// <param name="fileDto">This should be a CmFile object.</param> /// <returns></returns> private string GetCmFilePath(DomainObjectDTO fileDto) { XElement cmFileXML = XElement.Parse(fileDto.Xml); var InternalPath = cmFileXML.XPathSelectElement("InternalPath"); var filePathFromCmFile = cmFileXML.XPathSelectElement("InternalPath").XPathSelectElement("Uni").Value; return filePathFromCmFile; }
private static void UpdateObjSurElement(IDomainObjectDTORepository dtoRepos, DomainObjectDTO dto, string oldGuid, string newGuid) { var rtElem = XElement.Parse(dto.Xml); var ownObjSurGuidAttr = (from objSurNode in rtElem.Descendants("objsur") where objSurNode.Attribute("guid").Value.ToLower() == oldGuid.ToLower() select objSurNode.Attribute("guid")).FirstOrDefault(); // Ought not be null, but play it safe. if (ownObjSurGuidAttr != null) ownObjSurGuidAttr.Value = newGuid; UpdateDTO(dtoRepos, dto, rtElem.ToString()); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Removes the specified field. /// </summary> /// <param name="dto">The domain transfer object that has a field that may need to be deleted.</param> /// <param name="objElement">Name of the object containing fieldToDelete.</param> /// <param name="fieldToDelete">The name of the field to delete.</param> /// ------------------------------------------------------------------------------------ private void RemoveField(DomainObjectDTO dto, XElement objElement, string fieldToDelete) { XElement rmElement = objElement.Element(fieldToDelete); if (rmElement != null) rmElement.Remove(); }
private string GetCmFileGuid(DomainObjectDTO fileDto) { XElement cmFileXML = XElement.Parse(fileDto.Xml); var cmFileGuid = cmFileXML.Attribute("guid").Value; return cmFileGuid; }