/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Changes all StTxtParas that are owned by Scripture to be ScrTxtParas
		/// </summary>
		/// <param name="domainObjectDtoRepository">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// <remarks>
		/// The method must add/remove/update the DTOs to the repository,
		/// as it adds/removes objects as part of it work.
		///
		/// Implementors of this interface should ensure the Repository's
		/// starting model version number is correct for the step.
		/// Implementors must also increment the Repository's model version number
		/// at the end of its migration work.
		///
		/// The method also should normally modify the xml string(s)
		/// of relevant DTOs, since that string will be used by the main
		/// data migration calling client (ie. BEP).
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000001);

			var parasToChangeClasses = new List<DomainObjectDTO>();
			foreach (var stTxtPara in domainObjectDtoRepository.AllInstancesSansSubclasses("StTxtPara"))
			{
				var paraOwner = domainObjectDtoRepository.GetOwningDTO(stTxtPara);
				if (paraOwner.Classname != "StText" && paraOwner.Classname != "StFootnote")
				{
					continue; // Paragraph is not owned by an StText or StFootnote (shouldn't ever happen)
				}

				var textOwner = domainObjectDtoRepository.GetOwningDTO(paraOwner);
				if (textOwner.Classname != "ScrBook" && textOwner.Classname != "ScrSection")
				{
					continue; // StText is not part of Scripture, don't change.
				}
				// Its one of the paragraphs that we care about. We just need to change the
				// class in the xml to be a ScrTxtPara and change the objectsByClass map.
				DataMigrationServices.ChangeToSubClass(stTxtPara, "StTxtPara", "ScrTxtPara");
				parasToChangeClasses.Add(stTxtPara);
			}

			// Udate the repository
			var startingStructure = new ClassStructureInfo("StPara", "StTxtPara");
			var endingStructure = new ClassStructureInfo("StTxtPara", "ScrTxtPara");
			foreach (var changedPara in parasToChangeClasses)
				domainObjectDtoRepository.Update(changedPara,
					startingStructure,
					endingStructure);

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Changes all StFootnotes to ScrFootnotes
		/// </summary>
		/// <param name="domainObjectDtoRepository">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// <remarks>
		/// The method must add/remove/update the DTOs to the repository,
		/// as it adds/removes objects as part of it work.
		///
		/// Implementors of this interface should ensure the Repository's
		/// starting model version number is correct for the step.
		/// Implementors must also increment the Repository's model version number
		/// at the end of its migration work.
		///
		/// The method also should normally modify the xml string(s)
		/// of relevant DTOs, since that string will be used by the main
		/// data migration calling client (ie. BEP).
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000002);

			var footnotesToChangeClasses = new List<DomainObjectDTO>();
			foreach (var footnote in domainObjectDtoRepository.AllInstancesSansSubclasses("StFootnote"))
			{
				XElement footnoteEl = XElement.Parse(footnote.Xml);
				footnoteEl.Attribute("class").Value = "ScrFootnote";

				// Add the empty ScrFootnote element to the ScrFootnote
				footnoteEl.Add(new XElement("ScrFootnote"));

				// Update the object XML
				footnote.Xml = footnoteEl.ToString();
				footnote.Classname = "ScrFootnote";
				footnotesToChangeClasses.Add(footnote);
			}

			// Udate the repository
			var startingStructure = new ClassStructureInfo("StText", "StFootnote");
			var endingStructure = new ClassStructureInfo("StFootnote", "ScrFootnote");
			foreach (var changedPara in footnotesToChangeClasses)
				domainObjectDtoRepository.Update(changedPara,
					startingStructure,
					endingStructure);

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		private void VerifyReplace(IDomainObjectDTORepository dtoRepos, string guid, bool expectReplace, int numOfPubs)
		{
			var dto = dtoRepos.GetDTO(guid);
			var xElt = XElement.Parse(dto.Xml);
			Assert.That(xElt.Attribute("class").Value == "LexEntry", "Giud not representing a LexEntry after migration to 7000041.");
			var hasDoNotShow = xElt.Element("DoNotShowMainEntryIn");
			string expect = "";
			if (!expectReplace)
				expect = "not ";
			Assert.That(expectReplace == (hasDoNotShow != null),
				"LexEntry " + guid + " did " + expect + "expect ExcludeAsHeadword to be replaced by DoNotShowMainEntryIn, but it didn't happen in migration to 7000041.");
			if (expectReplace)
			{ // Check that each publication is referenced
				var noShows = SurrogatesIn(xElt, "DoNotShowMainEntryIn", numOfPubs);
				var dtoPubist = dtoRepos.GetDTO(CmPossibilityListTags.kguidPublicationsList.ToString());
				Assert.That(dtoPubist != null, "This project has no Publications list after migration 7000041");
				var xPubist = XElement.Parse(dtoPubist.Xml);
				var cfElements = SurrogatesIn(xPubist, "Possibilities", numOfPubs);
				foreach (var xObj in cfElements)
				{	// there must be 1 to 1 map of objsur's in hasDoNotShow and xPubist
					string pubGuid = xObj.Attribute("guid").Value;
					int n = 0;
					foreach (var yObj in noShows)
					{
						if (pubGuid == yObj.Attribute("guid").Value)
						{
							Assert.That(yObj.Attribute("t").Value == "r", "7000041 Migrated test XML pub list items are not references");
							break;
						}
					}
				}
			}
		}
		/// <summary>
		/// Remove the owningFlid attribute from every "rt" element.
		/// </summary>
		/// <param name="domainObjectDtoRepository"></param>
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000008);

			foreach (var dto in domainObjectDtoRepository.AllInstancesWithValidClasses())
			{
				byte[] contents = dto.XmlBytes;
				int index = contents.IndexOfSubArray(owningFlidTag);
				if (index >= 0)
				{
					contents = contents.ReplaceSubArray(index,
						Array.IndexOf(contents, closeQuote, index + owningFlidTag.Length) - index + 1,
						new byte[0]);
				}
				int index2 = contents.IndexOfSubArray(owningOrdTag);
				if (index2 >= 0)
				{
					contents = contents.ReplaceSubArray(index2,
						Array.IndexOf(contents, closeQuote, index2 + owningOrdTag.Length) - index2 + 1,
						new byte[0]);
				}
				if (index >= 0 || index2 >= 0)
				{
					DataMigrationServices.UpdateDTO(domainObjectDtoRepository, dto, contents);
				}
			}
			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Change all guids to lowercase to help the Chorus diff/merge code.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000024);

			const string dateCreated = "DateCreated";
			var properties = new List<string> { dateCreated, "DateModified" };

			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("CmProject"), properties); // Tested
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("CmMajorObject"), properties); // Tested
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("CmPossibility"), properties); // Tested
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("CmAnnotation"), properties); // Tested
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("StJournalText"), properties); // Tested
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("LexEntry"), properties); // Tested
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("RnGenericRec"), properties); // Tested
			// Since ScrScriptureNote derives from CmBaseAnnotation, which has already had it DateCreated & DateModified updated,
			// we have to clear those two out of the dictioanry, or they will be updated twice, and the test on ScrScriptureNote will fail.
			properties.Clear();
			properties.Add("DateResolved");
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("ScrScriptureNote"), properties); // Tested
			properties.Clear();
			properties.Add(dateCreated);
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("ScrDraft"), properties);
			properties.Clear();
			properties.Add("RunDate");
			ConvertClassAndSubclasses(domainObjectDtoRepository, domainObjectDtoRepository.AllInstancesWithSubclasses("ScrCheckRun"), properties);

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000062);

			var wmbLangProjList = domainObjectDtoRepository.AllInstancesSansSubclasses("LangProject");
			var wmbLangProj = wmbLangProjList.First();
			var wmbLangProjElt = XElement.Parse(wmbLangProj.Xml);
			// get the default vernacular ws - it's the 1st in the list of current ones.
			var vernWss = wmbLangProjElt.Element("CurVernWss"); // has to be only one
			// a new project migrates before adding writing systems to the cache, so if there are no CurVernWss, bail out
			if (vernWss != null)
			{
				var vernWssUni = vernWss.Element("Uni"); // only one
				var vernWsList = vernWssUni.Value.Split(' '); // at least one
				var vernDefault = vernWsList[0]; // the default

				// Create the new property
				var sb = new StringBuilder();
				sb.Append("<HomographWs>");
				sb.AppendFormat("<Uni>{0}</Uni>", vernDefault);
				sb.Append("</HomographWs>");
				var hgWsElt = XElement.Parse(sb.ToString());
				wmbLangProjElt.Add(hgWsElt);
				DataMigrationServices.UpdateDTO(domainObjectDtoRepository, wmbLangProj, wmbLangProjElt.ToString());
			}

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Makes LexEntries be unowned.
		/// </summary>
		/// <param name="domainObjectDtoRepository">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// <remarks>
		/// The method must add/remove/update the DTOs to the repository,
		/// as it adds/removes objects as part of it work.
		///
		/// Implementors of this interface should ensure the Repository's
		/// starting model version number is correct for the step.
		/// Implementors must also increment the Repository's model version number
		/// at the end of its migration work.
		///
		/// The method also should normally modify the xml string(s)
		/// of relevant DTOs, since that string will be used by the main
		/// data migration calling client (ie. BEP).
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000027);

			var lexDbDto = domainObjectDtoRepository.AllInstancesSansSubclasses("LexDb").First();
			var lexDb = XElement.Parse(lexDbDto.Xml);
			var entries = lexDb.Element("Entries");
			if (entries != null)
			{
				entries.Remove();
				DataMigrationServices.UpdateDTO(domainObjectDtoRepository, lexDbDto, lexDb.ToString());
			}

			foreach (var entryDto in domainObjectDtoRepository.AllInstancesSansSubclasses("LexEntry"))
			{
				XElement entry = XElement.Parse(entryDto.Xml);
				var ownerAttr = entry.Attribute("ownerguid");
				if (ownerAttr != null)
				{
					ownerAttr.Remove();
					DataMigrationServices.UpdateDTO(domainObjectDtoRepository, entryDto, entry.ToString());
				}
			}

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Change any bogus non-owning footnote links in the vernacular (but NOT in the BT)
		/// to be owning links
		/// </summary>
		/// <param name="domainObjectDtoRepository">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000034);

			foreach (var scrTxtPara in domainObjectDtoRepository.AllInstancesSansSubclasses("ScrTxtPara"))
			{
				XElement para = XElement.Parse(scrTxtPara.Xml);
				XElement contents = para.Element("Contents");
				if (contents == null)
					continue;
				XElement str = contents.Element("Str");
				if (str == null)
					continue;

				foreach (XElement run in str.Elements("Run"))
				{
					XAttribute linkAttr = run.Attribute("link");
					if (linkAttr == null)
						continue; // Run doesn't contain an unowned hot-link
					XAttribute ownedLinkAttr = new XAttribute("ownlink", linkAttr.Value);
					run.Add(ownedLinkAttr);
					linkAttr.Remove();
					DataMigrationServices.UpdateDTO(domainObjectDtoRepository, scrTxtPara, para.ToString());
				}
			}

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		/// <summary>
		/// The Weather list is never used, so delete it (and remove any empty Weather elements
		/// from the RnGenericRec elements).
		/// </summary>
		private void DeleteWeatherListAndField(IDomainObjectDTORepository repoDTO)
		{
			// Remove the Weather list.
			DomainObjectDTO dtoLP = GetDtoLangProj(repoDTO);
			string sWeatherListGuid = RemoveWeatherConditionsElement(dtoLP).ToLowerInvariant();
			repoDTO.Update(dtoLP);
			DomainObjectDTO dtoDeadList = null;
			foreach (var dto in repoDTO.AllInstancesWithSubclasses("CmPossibilityList"))
			{
				if (dto.Guid.ToLowerInvariant() == sWeatherListGuid)
				{
					dtoDeadList = dto;
					break;
				}
			}
			List<DomainObjectDTO> rgdtoDead = new List<DomainObjectDTO>();
			GatherDeadObjects(repoDTO, dtoDeadList, rgdtoDead);
			foreach (var dto in rgdtoDead)
				repoDTO.Remove(dto);

			// Remove any empty Weather elements in the RnGenericRec objects.
			foreach (var dto in repoDTO.AllInstancesWithSubclasses("RnGenericRec"))
			{
				string sXml = dto.Xml;
				int idx = sXml.IndexOf("<Weather");
				if (idx > 0)
				{
					dto.Xml = RemoveEmptyWeather(sXml, idx);
					repoDTO.Update(dto);
				}
			}
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Perform one increment migration step.
		///
		/// In this case, the migration is not related to a model change,
		/// but is a simple data change that removes the class elements in the xml.
		/// The end resujlt xml will have the top-level 'rt' element and zero, or more,
		/// property level elements.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000014);

			// No. We need to convert all instances, even if they are no longer part of the model.
			// DM19, for example, removes LgWritingSystem instances and the class form the model,
			// but it tries to access the data as if it had been properly processed by DM15,
			// *but* this code would leave out LgWritingSystem instnaces form being processed here.
			//foreach (var dto in domainObjectDtoRepository.AllInstancesWithSubclasses("CmObject"))
			foreach (var dto in domainObjectDtoRepository.AllInstances())
			{
				var rtElement = XElement.Parse(dto.Xml);
				// Removes all current child nodes (class level),
				// and replaces them with the old property nodes (if any).
#if !__MonoCS__
				rtElement.ReplaceNodes(rtElement.Elements().Elements());
				dto.Xml = rtElement.ToString();
#else // FWNX-165: work around mono bug https://bugzilla.novell.com/show_bug.cgi?id=592435
				var copy = new XElement(rtElement);
				copy.ReplaceNodes(rtElement.Elements().Elements());
				dto.Xml = copy.ToString();
#endif
				domainObjectDtoRepository.Update(dto);
			}

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Perform one increment migration step.
		/// </summary>
		/// <param name="domainObjectDtoRepository">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// <remarks>
		/// The method must add/remove/update the DTOs to the repository,
		/// as it adds/removes objects as part of it work.
		///
		/// Implementors of this interface should ensure the Repository's
		/// starting model version number is correct for the step.
		/// Implementors must also increment the Repository's model version number
		/// at the end of its migration work.
		///
		/// The method also should normally modify the xml string(s)
		/// of relevant DTOs, since that string will be used by the main
		/// data migration calling client (ie. BEP).
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000000);

			DataMigrationServices.Delint(domainObjectDtoRepository);

			var lpDto = domainObjectDtoRepository.AllInstancesSansSubclasses("LangProject").First();
			// 1. Remove property from LangProg.
			var lpElement = XElement.Parse(lpDto.Xml);
			lpElement.Descendants("WordformInventory").Remove();
			DataMigrationServices.UpdateDTO(domainObjectDtoRepository, lpDto, lpElement.ToString());

			// 2. Remove three owner-related attributes from each WfiWordform.
			// (There may be zero, or more, instances to upgrade.)
			foreach (var wordformDto in domainObjectDtoRepository.AllInstancesSansSubclasses("WfiWordform"))
			{
				var wfElement = XElement.Parse(wordformDto.Xml);
				wfElement.Attribute("ownerguid").Remove();
				var flidAttr = wfElement.Attribute("owningflid");
				if (flidAttr != null)
					flidAttr.Remove();
				var ordAttr = wfElement.Attribute("owningord");
				if (ordAttr != null)
					ordAttr.Remove();
				DataMigrationServices.UpdateDTO(domainObjectDtoRepository, wordformDto, wfElement.ToString());
			}

			// 3. Remove WordformInventory instance.
			domainObjectDtoRepository.Remove(
				domainObjectDtoRepository.AllInstancesSansSubclasses("WordformInventory").First());

			// There are no references to the WFI, so don't fret about leaving dangling refs to it.

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		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>
		/// Looks for CmFile objects included in LangProject. If found, will look for CmFile in
		/// correct location and replace reference on CmPicture with that new CmFile.
		/// </summary>
		/// <param name="repoDto">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// <remarks>
		/// Implementors of this interface should ensure the Repository's
		/// starting model version number is correct for the step.
		/// Implementors must also increment the Repository's model version number
		/// at the end of its migration work.
		///
		/// The method also should normally modify the xml string(s)
		/// of relevant DTOs, since that string will be used by the main
		/// data migration calling client (ie. BEP).
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository repoDto)
		{
			DataMigrationServices.CheckVersionNumber(repoDto, 7000033);
			var langProj = repoDto.AllInstancesSansSubclasses("LangProject").First();
			var langProjElement = XElement.Parse(langProj.Xml);
			var pictures = langProjElement.Element("Pictures");

			if (pictures != null && pictures.Elements().Count() > 1)
			{
				DomainObjectDTO folder = null;
				bool foundFiles = false;
				foreach (var x in pictures.Elements())
				{
					var xObj = repoDto.GetDTO(x.Attribute("guid").Value);
					if (xObj.Classname == "CmFolder")
					{
						// empty folders can just be removed
						var xObjElement = XElement.Parse(xObj.Xml);
						if (xObjElement.Element("Files") == null)
							DataMigrationServices.RemoveIncludingOwnedObjects(repoDto, xObj, true);
						else if (folder == null)
							folder = xObj;
						else
							MoveFileReferences(repoDto, langProj, xObj, folder);
					}
					else
						foundFiles = true;
				}

				if (folder != null && foundFiles)
					RemoveInvalidFiles(repoDto, langProj, folder);

			}
			DataMigrationServices.IncrementVersionNumber(repoDto);
		}
Example #14
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Change model for Data Notebook to combine the RnEvent and RnAnalysis classes
        /// into RnGenericRec
        /// </summary>
        /// <param name="domainObjectDtoRepository">
        /// Repository of all CmObject DTOs available for one migration step.
        /// </param>
        /// <remarks>
        /// The method must add/remove/update the DTOs to the repository,
        /// as it adds/removes objects as part of its work.
        ///
        /// Implementors of this interface should ensure the Repository's
        /// starting model version number is correct for the step.
        /// Implementors must also increment the Repository's model version number
        /// at the end of its migration work.
        ///
        /// The method also should normally modify the xml string(s)
        /// of relevant DTOs, since that string will be used by the main
        /// data migration calling client (ie. BEP).
        /// </remarks>
        /// ------------------------------------------------------------------------------------
        public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
        {
            DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000004);

            // 1. Change EventTypes field to RecTypes
            var nbkDto            = domainObjectDtoRepository.AllInstancesSansSubclasses("RnResearchNbk").First();
            var nbkElement        = XElement.Parse(nbkDto.Xml);
            var nbkClsElement     = nbkElement.Element("RnResearchNbk");
            var typesFieldElement = nbkClsElement.Element("EventTypes");
            var typesSurElement   = typesFieldElement.Element("objsur");

            nbkClsElement.Add(new XElement("RecTypes", typesSurElement));
            typesFieldElement.Remove();
            DataMigrationServices.UpdateDTO(domainObjectDtoRepository, nbkDto, nbkElement.ToString());

            // 2. Add Analysis possibility to Record Types list
            var typesGuid    = typesSurElement.Attribute("guid").Value;
            var typesDto     = domainObjectDtoRepository.GetDTO(typesGuid);
            var typesElement = XElement.Parse(typesDto.Xml);

            typesElement.XPathSelectElement("CmMajorObject/Name/AUni[@ws='en']").SetValue("Entry Types");
            var posElement = typesElement.XPathSelectElement("CmPossibilityList/Possibilities");

            posElement.Add(
                DataMigrationServices.CreateOwningObjSurElement("82290763-1633-4998-8317-0EC3F5027FBD"));
            DataMigrationServices.UpdateDTO(domainObjectDtoRepository, typesDto,
                                            typesElement.ToString());
            var ord = posElement.Elements().Count();

            var nowStr      = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var typeElement = new XElement("rt", new XAttribute("class", "CmPossibility"),
                                           new XAttribute("guid", "82290763-1633-4998-8317-0EC3F5027FBD"),
                                           new XAttribute("ownerguid", typesGuid),
                                           new XAttribute("owningflid", "8008"), new XAttribute("owningord", ord.ToString()),
                                           new XElement("CmObject"),
                                           new XElement("CmPossibility",
                                                        new XElement("Abbreviation",
                                                                     new XElement("AUni", new XAttribute("ws", "en"), "Ana")),
                                                        new XElement("BackColor", new XAttribute("val", "16711680")),
                                                        new XElement("DateCreated", new XAttribute("val", nowStr)),
                                                        new XElement("DateModified", new XAttribute("val", nowStr)),
                                                        new XElement("Description",
                                                                     new XElement("AStr", new XAttribute("ws", "en"),
                                                                                  new XElement("Run", new XAttribute("ws", "en"), "Reflection on events and other types of data, such as literature summaries or interviews. An analysis does not add data; it interprets and organizes data. An analysis entry may synthesize emerging themes. It may draw connections between observations. It is a place to speculate and hypothesize, or document moments of discovery and awareness. Analytic notes can be turned into articles. Or, they may just be steps on the stairway toward greater understanding."))),
                                                        new XElement("ForeColor", new XAttribute("val", "16777215")),
                                                        new XElement("Name",
                                                                     new XElement("AUni", new XAttribute("ws", "en"), "Analysis")),
                                                        new XElement("UnderColor", new XAttribute("val", "255")),
                                                        new XElement("UnderStyle", new XAttribute("val", "1"))));

            domainObjectDtoRepository.Add(new DomainObjectDTO("82290763-1633-4998-8317-0EC3F5027FBD",
                                                              "CmPossibility", typeElement.ToString()));

            // 3. Move the attributes that are in RnEvent and RnAnalysis into RnGenericRec.
            MigrateSubclassOfGenRec(domainObjectDtoRepository, "RnEvent");
            MigrateSubclassOfGenRec(domainObjectDtoRepository, "RnAnalysis");

            DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
        }
Example #15
0
 /// <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);
     }
 }
Example #16
0
        /// <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);
                }
            }
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// 1) Remove orphaned CmBaseAnnotations, as per FWR-98:
        /// "Since we won't try to reuse wfic or segment annotations that no longer have
        /// BeginObject point to a paragraph, we should remove (ignore) these annotations
        /// when migrating an old database (FW 6.0 or older) into the new architecture"
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
        {
            DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000007);

/* Expected data (relevant data, that is) format.
 *                      <rt guid="22a8431f-f974-412f-a261-8bd1a4e1be1b" class="CmBaseAnnotation">
 *                              <CmObject />
 *                              <CmAnnotation>
 *                                      <AnnotationType> <!-- Entire element will be missing if prop is null. -->
 *                                              <objsur guid="eb92e50f-ba96-4d1d-b632-057b5c274132" t="r" />
 *                                      </AnnotationType>
 *                              </CmAnnotation>
 *                              <CmBaseAnnotation>
 *                                      <BeginObject> <!-- Entire element will be missing if prop is null. -->
 *                                              <objsur guid="93dcb15d-f622-4329-b1b5-e5cc832daf01" t="r" />
 *                                      </BeginObject>
 *                              </CmBaseAnnotation>
 *                      </rt>
 */
            var interestingAnnDefIds = new List <string>
            {
                DataMigrationServices.kSegmentAnnDefnGuid.ToLower(),
                DataMigrationServices.kTwficAnnDefnGuid.ToLower(),
                DataMigrationServices.kPficAnnDefnGuid.ToLower(),
                DataMigrationServices.kConstituentChartAnnotationAnnDefnGuid.ToLower()
            };

            //Collect up the ones to be removed.
            var goners = new List <DomainObjectDTO>();

            foreach (var annDTO in domainObjectDtoRepository.AllInstancesSansSubclasses("CmBaseAnnotation"))
            {
                var annElement  = XElement.Parse(annDTO.Xml);
                var typeElement = annElement.Element("CmAnnotation").Element("AnnotationType");
                if (typeElement == null ||
                    !interestingAnnDefIds.Contains(typeElement.Element("objsur").Attribute("guid").Value.ToLower()))
                {
                    continue;                     // uninteresing annotation type, so skip it.
                }
                // annDTO is a segment, wordform, punctform, or constituent chart annotation.
                if (annElement.Element("CmBaseAnnotation").Element("BeginObject") != null)
                {
                    continue;                     // Has data in BeginObject property, so skip it.
                }
                goners.Add(annDTO);
            }

            // Remove them.
            foreach (var goner in goners)
            {
                DataMigrationServices.RemoveIncludingOwnedObjects(domainObjectDtoRepository, goner, true);
            }

            // Some stuff may reference the defective Discourse Cahrt Annotation, so clear out the refs to them.
            DataMigrationServices.Delint(domainObjectDtoRepository);

            DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
        }
		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 PerformMigration(IDomainObjectDTORepository repoDto)
        {
            DataMigrationServices.CheckVersionNumber(repoDto, 7000069);

            CleanOutBadRefTypes(repoDto);
            RenameDuplicateCustomListsAndFixBadLists(repoDto);

            DataMigrationServices.IncrementVersionNumber(repoDto);
        }
        private static XElement GetPossibilityListNameElement(IDomainObjectDTORepository dtoRepos,
                                                              XElement ownerElement, string flidName)
        {
            Assert.IsNotNull(ownerElement.XPathSelectElement(flidName));
            var xPath = flidName + "/objsur";
            var dto   = dtoRepos.GetDTO(ownerElement.XPathSelectElement(xPath).Attribute("guid").Value);

            return(XElement.Parse(dto.Xml).XPathSelectElement("Name"));
        }
        /// <summary>We update every instance of a Restriction in a LexEntry or a LexSense to change from AUni to AStr.</summary>
        private static void UpdateRestrictions(IDomainObjectDTORepository repoDto)
        {
            var xpathToRestrictionsElt = "//Restrictions";

            foreach (var entryOrSenseDto in repoDto.AllInstancesSansSubclasses("LexEntry").Union(repoDto.AllInstancesSansSubclasses("LexSense")))
            {
                ChangeMultiUnicodeElementToMultiString(repoDto, entryOrSenseDto, xpathToRestrictionsElt);
            }
        }
Example #22
0
 private static void RemoveEmptyPropertyElements(
     IDomainObjectDTORepository dtoRepos,
     IEnumerable <DomainObjectDTO> allInstancesWithValidClasses)
 {
     foreach (var currentDto in allInstancesWithValidClasses)
     {
         RemoveEmptyPropertyElements(dtoRepos, currentDto, XElement.Parse(currentDto.Xml));
     }
 }
Example #23
0
        /// <summary>
        /// Increment the model version number for the repository.
        /// </summary>
        internal static void IncrementVersionNumber(IDomainObjectDTORepository dtoRepos)
        {
            if (dtoRepos == null)
            {
                throw new ArgumentNullException("dtoRepos");
            }

            dtoRepos.CurrentModelVersion = dtoRepos.CurrentModelVersion + 1;
        }
		private void RemoveUnwantedOverlays(IDomainObjectDTORepository repoDTO, List<DomainObjectDTO> collectOverlaysToRemove)
		{
			DomainObjectDTO dtoLP = GetDtoLangProj(repoDTO);
			foreach (var dto in collectOverlaysToRemove)
			{
				RemoveOverlayElement(dtoLP, dto.Guid);
				repoDTO.Remove(dto);
			}
		}
Example #25
0
 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);
     }
 }
		private XElement[] VerifyEntryRef(IDomainObjectDTORepository dtoRepos, string guid, int cfCount, int showComplexFormsInCount)
		{
			var dto = dtoRepos.GetDTO(guid);
			var xElt = XElement.Parse(dto.Xml);
			SurrogatesIn(xElt, "ComponentLexemes", cfCount);
			SurrogatesIn(xElt, "PrimaryLexemes", showComplexFormsInCount);
			var cfElements = SurrogatesIn(xElt, "ShowComplexFormsIn", showComplexFormsInCount);
			return cfElements.ToArray();
		}
		/// <summary>
		/// Updates the Data Notebook RecordTypes possibilities to use specific GUIDs.
		/// </summary>
		/// <param name="domainObjectDtoRepository">Repository of all CmObject DTOs available for one migration step.</param>
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000010);

			DomainObjectDTO nbkDto = domainObjectDtoRepository.AllInstancesSansSubclasses("RnResearchNbk").First();
			XElement nbkElem = XElement.Parse(nbkDto.Xml);
			var recTypesGuid = (string) nbkElem.XPathSelectElement("RnResearchNbk/RecTypes/objsur").Attribute("guid");
			var stack = new Stack<DomainObjectDTO>(domainObjectDtoRepository.GetDirectlyOwnedDTOs(recTypesGuid));
			IEnumerable<DomainObjectDTO> recDtos = domainObjectDtoRepository.AllInstancesSansSubclasses("RnGenericRec");
			IEnumerable<DomainObjectDTO> overlayDtos = domainObjectDtoRepository.AllInstancesSansSubclasses("CmOverlay");
			while (stack.Count > 0)
			{
				DomainObjectDTO dto = stack.Pop();
				foreach (DomainObjectDTO childDto in domainObjectDtoRepository.GetDirectlyOwnedDTOs(dto.Guid))
					stack.Push(childDto);
				XElement posElem = XElement.Parse(dto.Xml);
				XElement uniElem = posElem.XPathSelectElement("CmPossibility/Abbreviation/AUni[@ws='en']");
				if (uniElem != null)
				{
					string newGuid = null;
					switch (uniElem.Value)
					{
						case "Con":
							newGuid = "B7B37B86-EA5E-11DE-80E9-0013722F8DEC";
							break;
						case "Intv":
							newGuid = "B7BF673E-EA5E-11DE-9C4D-0013722F8DEC";
							break;
						case "Str":
							newGuid = "B7C8F092-EA5E-11DE-8D7D-0013722F8DEC";
							break;
						case "Uns":
							newGuid = "B7D4DC4A-EA5E-11DE-867C-0013722F8DEC";
							break;
						case "Lit":
							newGuid = "B7E0C7F8-EA5E-11DE-82CC-0013722F8DEC";
							break;
						case "Obs":
							newGuid = "B7EA5156-EA5E-11DE-9F9C-0013722F8DEC";
							break;
						case "Per":
							newGuid = "B7F63D0E-EA5E-11DE-9F02-0013722F8DEC";
							break;
						case "Ana":
							newGuid = "82290763-1633-4998-8317-0EC3F5027FBD";
							break;
					}
					if (newGuid != null)
						DataMigrationServices.ChangeGuid(domainObjectDtoRepository, dto, newGuid, recDtos.Concat(overlayDtos));
				}
			}

			DomainObjectDTO recTypesDto = domainObjectDtoRepository.GetDTO(recTypesGuid);
			DataMigrationServices.ChangeGuid(domainObjectDtoRepository, recTypesDto, "D9D55B12-EA5E-11DE-95EF-0013722F8DEC", overlayDtos);
			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// locate all files in %appdata%/SIL/FieldWorks/Language Explorer/db$projectname$*.* and move them
        /// to projects/projectname/ConfigurationSettings/db$local$*.*
        /// </summary>
        /// <param name="repoDto">
        /// Repository of all CmObject DTOs available for one migration step.
        /// </param>
        /// <remarks>
        /// Implementors of this interface should ensure the Repository's
        /// starting model version number is correct for the step.
        /// Implementors must also increment the Repository's model version number
        /// at the end of its migration work.
        ///
        /// The method also should normally modify the xml string(s)
        /// of relevant DTOs, since that string will be used by the main
        /// data migration calling client (ie. BEP).
        /// </remarks>
        /// ------------------------------------------------------------------------------------
        public void PerformMigration(IDomainObjectDTORepository repoDto)
        {
            DataMigrationServices.CheckVersionNumber(repoDto, 7000031);
            var projectFolder = repoDto.ProjectFolder;
            var projectName   = Path.GetFileNameWithoutExtension(projectFolder);
            // This is equivalent to DirectoryFinder.UserAppDataFolder("Language Explorer") at the time of creating
            // the migration, but could conceivably change later.
            var sourceDir = Path.Combine(
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SIL"),
                "Language Explorer");
            // This is equivalent to DirectoryFinder.GetConfigSettingsDir(projectFolder) at the time of creating
            // the migration, but could conceivably change later.
            var targetDir = Path.Combine(projectFolder, "ConfigurationSettings");

            if (Directory.Exists(sourceDir))
            {
                Directory.CreateDirectory(targetDir);
                string       oldPrefix = "db$" + projectName + "$";
                const string newPrefix = "db$local$";
                foreach (var path in Directory.GetFiles(sourceDir, oldPrefix + "*.*"))
                {
                    var filename = Path.GetFileName(path);
                    if (filename == null)
                    {
                        continue;
                    }
                    var targetName = filename.Substring(oldPrefix.Length);
                    if (targetName.ToLowerInvariant() == "settings.xml")
                    {
                        targetName = newPrefix + targetName;
                        var destFileName1 = Path.Combine(targetDir, targetName);
                        if (!File.Exists(destFileName1))
                        {
                            // The settings file contains saved properties that begin with db$ProjectName$ and need to be db$Local$
                            using (var reader = new StreamReader(path, Encoding.UTF8))
                            {
                                using (var writer = FileUtils.OpenFileForWrite(destFileName1, Encoding.UTF8))
                                {
                                    while (!reader.EndOfStream)
                                    {
                                        writer.WriteLine(reader.ReadLine().Replace(oldPrefix, newPrefix));
                                    }
                                }
                            }
                        }
                    }
                    var destFileName = Path.Combine(targetDir, targetName);
                    if (!File.Exists(destFileName))
                    {
                        File.Copy(path, destFileName);
                    }
                }
            }

            DataMigrationServices.IncrementVersionNumber(repoDto);
        }
		/// <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);
		}
Example #30
0
        private void RemoveUnwantedOverlays(IDomainObjectDTORepository repoDTO, List <DomainObjectDTO> collectOverlaysToRemove)
        {
            DomainObjectDTO dtoLP = GetDtoLangProj(repoDTO);

            foreach (var dto in collectOverlaysToRemove)
            {
                RemoveOverlayElement(dtoLP, dto.Guid);
                repoDTO.Remove(dto);
            }
        }
Example #31
0
        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));
        }
		/// <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);
		}
		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 static void CheckMainObject(IDomainObjectDTORepository dtoRepos, string guid, IEnumerable <KeyValuePair <string, string> > propertiesToCheck)
        {
            var dto       = dtoRepos.GetDTO(guid);
            var rtElement = XElement.Parse(dto.Xml);

            foreach (var kvp in propertiesToCheck)
            {
                CheckProperty(rtElement, kvp);
            }
        }
        private void AppendCustomToNamesAndUpdate(IDomainObjectDTORepository repoDto, DomainObjectDTO dto, XElement dtoXml)
        {
            var names = dtoXml.Elements("Name");

            foreach (var titleElement in names.Select(name => name.Element("AUni")).Where(titleElement => titleElement != null))
            {
                titleElement.Value = titleElement.Value + "-Custom";
            }
            DataMigrationServices.UpdateDTO(repoDto, dto, dtoXml.ToString());
        }
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Change model for Data Notebook to combine the RnEvent and RnAnalysis classes
		/// into RnGenericRec
		/// </summary>
		/// <param name="domainObjectDtoRepository">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// <remarks>
		/// The method must add/remove/update the DTOs to the repository,
		/// as it adds/removes objects as part of its work.
		///
		/// Implementors of this interface should ensure the Repository's
		/// starting model version number is correct for the step.
		/// Implementors must also increment the Repository's model version number
		/// at the end of its migration work.
		///
		/// The method also should normally modify the xml string(s)
		/// of relevant DTOs, since that string will be used by the main
		/// data migration calling client (ie. BEP).
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000004);

			// 1. Change EventTypes field to RecTypes
			var nbkDto = domainObjectDtoRepository.AllInstancesSansSubclasses("RnResearchNbk").First();
			var nbkElement = XElement.Parse(nbkDto.Xml);
			var nbkClsElement = nbkElement.Element("RnResearchNbk");
			var typesFieldElement = nbkClsElement.Element("EventTypes");
			var typesSurElement = typesFieldElement.Element("objsur");
			nbkClsElement.Add(new XElement("RecTypes", typesSurElement));
			typesFieldElement.Remove();
			DataMigrationServices.UpdateDTO(domainObjectDtoRepository, nbkDto, nbkElement.ToString());

			// 2. Add Analysis possibility to Record Types list
			var typesGuid = typesSurElement.Attribute("guid").Value;
			var typesDto = domainObjectDtoRepository.GetDTO(typesGuid);
			var typesElement = XElement.Parse(typesDto.Xml);
			typesElement.XPathSelectElement("CmMajorObject/Name/AUni[@ws='en']").SetValue("Entry Types");
			var posElement = typesElement.XPathSelectElement("CmPossibilityList/Possibilities");
			posElement.Add(
				DataMigrationServices.CreateOwningObjSurElement("82290763-1633-4998-8317-0EC3F5027FBD"));
			DataMigrationServices.UpdateDTO(domainObjectDtoRepository, typesDto,
				typesElement.ToString());
			var ord = posElement.Elements().Count();

			var nowStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
			var typeElement = new XElement("rt", new XAttribute("class", "CmPossibility"),
				new XAttribute("guid", "82290763-1633-4998-8317-0EC3F5027FBD"),
				new XAttribute("ownerguid", typesGuid),
				new XAttribute("owningflid", "8008"), new XAttribute("owningord", ord.ToString()),
				new XElement("CmObject"),
				new XElement("CmPossibility",
					new XElement("Abbreviation",
						new XElement("AUni", new XAttribute("ws", "en"), "Ana")),
					new XElement("BackColor", new XAttribute("val", "16711680")),
					new XElement("DateCreated", new XAttribute("val", nowStr)),
					new XElement("DateModified", new XAttribute("val", nowStr)),
					new XElement("Description",
						new XElement("AStr", new XAttribute("ws", "en"),
							new XElement("Run", new XAttribute("ws", "en"), "Reflection on events and other types of data, such as literature summaries or interviews. An analysis does not add data; it interprets and organizes data. An analysis entry may synthesize emerging themes. It may draw connections between observations. It is a place to speculate and hypothesize, or document moments of discovery and awareness. Analytic notes can be turned into articles. Or, they may just be steps on the stairway toward greater understanding."))),
					new XElement("ForeColor", new XAttribute("val", "16777215")),
					new XElement("Name",
						new XElement("AUni", new XAttribute("ws", "en"), "Analysis")),
					new XElement("UnderColor", new XAttribute("val", "255")),
					new XElement("UnderStyle", new XAttribute("val", "1"))));
			domainObjectDtoRepository.Add(new DomainObjectDTO("82290763-1633-4998-8317-0EC3F5027FBD",
				"CmPossibility", typeElement.ToString()));

			// 3. Move the attributes that are in RnEvent and RnAnalysis into RnGenericRec.
			MigrateSubclassOfGenRec(domainObjectDtoRepository, "RnEvent");
			MigrateSubclassOfGenRec(domainObjectDtoRepository, "RnAnalysis");

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
Example #37
0
        private DomainObjectDTO GetDtoLangProj(IDomainObjectDTORepository repoDTO)
        {
            DomainObjectDTO dtoLP = null;

            foreach (var dto in repoDTO.AllInstancesWithSubclasses("LangProject"))
            {
                dtoLP = dto;
                break;
            }
            return(dtoLP);
        }
Example #38
0
 /// <summary>
 /// Check the current verison number in the Repository against the given version number.
 /// </summary>
 internal static void CheckVersionNumber(IDomainObjectDTORepository dtoRepos, int expectedStartingModelVersionNumber)
 {
     if (dtoRepos == null)
     {
         throw new ArgumentNullException("dtoRepos");
     }
     if (dtoRepos.CurrentModelVersion != expectedStartingModelVersionNumber)
     {
         throw new DataMigrationException("Wrong version number to increment from.");
     }
 }
Example #39
0
        private XElement[] VerifyEntryRef(IDomainObjectDTORepository dtoRepos, string guid, int cfCount, int showComplexFormsInCount)
        {
            var dto  = dtoRepos.GetDTO(guid);
            var xElt = XElement.Parse(dto.Xml);

            SurrogatesIn(xElt, "ComponentLexemes", cfCount);
            SurrogatesIn(xElt, "PrimaryLexemes", showComplexFormsInCount);
            var cfElements = SurrogatesIn(xElt, "ShowComplexFormsIn", showComplexFormsInCount);

            return(cfElements.ToArray());
        }
Example #40
0
 private static DomainObjectDTO GetDTOIfItExists(IDomainObjectDTORepository dtoRepository, string sGuid)
 {
     try
     {
         return(dtoRepository.GetDTO(sGuid));
     }
     catch (ArgumentException)
     {
         return(null);
     }
 }
Example #41
0
        private List <string> ProcessExternalLinksRelativePaths(IDomainObjectDTORepository dtoRepos, String linkedFilesRootDir)
        {
            var filePathsInTsStrings = new List <string>();

            foreach (var dto in dtoRepos.AllInstancesWithValidClasses())              //Get the Elements for all CmObjects
            {
                if (dto.XmlBytes.IndexOfSubArray(externalLinkTag) < 0)
                {
                    continue;
                }
                var dtoXML = XElement.Parse(dto.Xml);
                foreach (var runXMLElement in dtoXML.XPathSelectElements("//Run"))
                {
                    var externalLinkAttributeForThisRun = runXMLElement.Attribute("externalLink");
                    if (externalLinkAttributeForThisRun != null)
                    {
                        try
                        {
                            //Convert the file paths which should be stored as relative paths
                            if (Path.IsPathRooted(FileUtils.ChangeWindowsPathIfLinux(externalLinkAttributeForThisRun.Value)))
                            {
                                var filePath = FileUtils.ChangeWindowsPathIfLinux(externalLinkAttributeForThisRun.Value);
                                //Check the path and if it is a rooted path which is relative to the LinkedFilesRootDir
                                //then we will have to confirm that is was changed to a relative path after the migration.
                                var fileAsRelativePath = LinkedFilesRelativePathHelper.GetRelativeLinkedFilesPath(filePath,
                                                                                                                  linkedFilesRootDir);
                                //Save the file paths so they can be turned into CmFiles
                                filePathsInTsStrings.Add(fileAsRelativePath);
                                //If these two strings do not match then a full path was converted to a LinkedFiles relative path
                                //so replace the path in the CmFile object.
                                if (!String.Equals(fileAsRelativePath, filePath))
                                {
                                    runXMLElement.Attribute("externalLink").Value = fileAsRelativePath;
                                    UpdateDto(dtoRepos, dto, dtoXML);
                                }
                            }
                            else
                            {
                                //if the file path was already relative we want to save it and turn it into a CmFiles
                                if (FileUtils.IsFileUriOrPath(externalLinkAttributeForThisRun.Value) && FileUtils.IsFilePathValid(externalLinkAttributeForThisRun.Value))
                                {
                                    filePathsInTsStrings.Add(externalLinkAttributeForThisRun.Value);
                                }
                            }
                        }
                        catch (ArgumentException)
                        {
                            Logger.WriteEvent("Invalid path for external link - no CmFile created: " + externalLinkAttributeForThisRun);
                        }
                    }
                }
            }
            return(filePathsInTsStrings);
        }
Example #42
0
        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);
        }
		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>
		/// 1) Remove orphaned CmBaseAnnotations, as per FWR-98:
		/// "Since we won't try to reuse wfic or segment annotations that no longer have
		/// BeginObject point to a paragraph, we should remove (ignore) these annotations
		/// when migrating an old database (FW 6.0 or older) into the new architecture"
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000007);

/* Expected data (relevant data, that is) format.
			<rt guid="22a8431f-f974-412f-a261-8bd1a4e1be1b" class="CmBaseAnnotation">
				<CmObject />
				<CmAnnotation>
					<AnnotationType> <!-- Entire element will be missing if prop is null. -->
						<objsur guid="eb92e50f-ba96-4d1d-b632-057b5c274132" t="r" />
					</AnnotationType>
				</CmAnnotation>
				<CmBaseAnnotation>
					<BeginObject> <!-- Entire element will be missing if prop is null. -->
						<objsur guid="93dcb15d-f622-4329-b1b5-e5cc832daf01" t="r" />
					</BeginObject>
				</CmBaseAnnotation>
			</rt>
*/
			var interestingAnnDefIds = new List<string>
				{
					DataMigrationServices.kSegmentAnnDefnGuid.ToLower(),
					DataMigrationServices.kTwficAnnDefnGuid.ToLower(),
					DataMigrationServices.kPficAnnDefnGuid.ToLower(),
					DataMigrationServices.kConstituentChartAnnotationAnnDefnGuid.ToLower()
				};

			//Collect up the ones to be removed.
			var goners = new List<DomainObjectDTO>();
			foreach (var annDTO in domainObjectDtoRepository.AllInstancesSansSubclasses("CmBaseAnnotation"))
			{
				var annElement = XElement.Parse(annDTO.Xml);
				var typeElement = annElement.Element("CmAnnotation").Element("AnnotationType");
				if (typeElement == null
					|| !interestingAnnDefIds.Contains(typeElement.Element("objsur").Attribute("guid").Value.ToLower()))
					continue; // uninteresing annotation type, so skip it.

				// annDTO is a segment, wordform, punctform, or constituent chart annotation.
				if (annElement.Element("CmBaseAnnotation").Element("BeginObject") != null)
					continue; // Has data in BeginObject property, so skip it.

				goners.Add(annDTO);
			}

			// Remove them.
			foreach (var goner in goners)
				DataMigrationServices.RemoveIncludingOwnedObjects(domainObjectDtoRepository, goner, true);

			// Some stuff may reference the defective Discourse Cahrt Annotation, so clear out the refs to them.
			DataMigrationServices.Delint(domainObjectDtoRepository);

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Looks for Configuration files ending in _Layouts.xml and fixes any custom field
		/// names used in them.
		/// </summary>
		/// <param name="repoDto">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// <remarks>
		/// Implementors of this interface should ensure the Repository's
		/// starting model version number is correct for the step.
		/// Implementors must also increment the Repository's model version number
		/// at the end of its migration work.
		///
		/// The method also should normally modify the xml string(s)
		/// of relevant DTOs, since that string will be used by the main
		/// data migration calling client (ie. BEP).
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository repoDto)
		{
			DataMigrationServices.CheckVersionNumber(repoDto, 7000032);
			var projectFolder = repoDto.ProjectFolder;
			// This is equivalent to FwDirectoryFinder.GetConfigSettingsDir(projectFolder) at the time of creating
			// the migration, but could conceivably change later.
			var targetDir = Path.Combine(projectFolder, "ConfigurationSettings");
			if (Directory.Exists(targetDir))
			{
				foreach (var path in Directory.GetFiles(targetDir, "*_Layouts.xml"))
				{
					var root = XElement.Load(path);
					bool fDirty = false;
					foreach (var part in root.Descendants("part"))
					{
						var firstChild = part.FirstNode as XElement;
						if (firstChild == null)
							continue;
						var fieldAttr = firstChild.Attribute("field");
						if (fieldAttr == null)
							continue;
						if (!fieldAttr.Value.StartsWith("custom"))
							continue;
						string tail = fieldAttr.Value.Substring("custom".Length);
						int dummy;
						if (tail.Length > 0 && !Int32.TryParse(tail, out dummy))
							continue; // not a plausible custom field from the old system
						var refAttr = part.Attribute("ref");
						if (refAttr == null || refAttr.Value != "$child")
							continue; // doesn't fit the pattern for generated custom field displays
						var labelAttr = part.Attribute("originalLabel");
						if (labelAttr == null)
						{
							labelAttr = part.Attribute("label");
							if (labelAttr == null)
								continue;
						}
						fieldAttr.Value = labelAttr.Value;
						fDirty = true;
					}
					if (fDirty)
					{
						using (var writer = XmlWriter.Create(path))
						{
							root.WriteTo(writer);
							writer.Close();
						}
					}
				}
			}

			DataMigrationServices.IncrementVersionNumber(repoDto);
		}
Example #46
0
        /// <summary>
        /// 1) Add the reference collection of Senses to each reversal index and
        /// fill it with the Senses that referenced the ReversalIndexEntry
        /// 2) Remove the collection of ReversalIndexEntry from each Sense
        /// 3) Migrate any VirtualOrdering objects if necessary
        /// </summary>
        public void PerformMigration(IDomainObjectDTORepository repoDto)
        {
            DataMigrationServices.CheckVersionNumber(repoDto, 7000071);

            AddSensesToReversalIndexEntry(repoDto);

            RemoveReversalEntriesFromSenses(repoDto);

            ChangeReferringSensesToSenses(repoDto);

            DataMigrationServices.IncrementVersionNumber(repoDto);
        }
Example #47
0
        public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
        {
            DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000065);

            // Cache all basic data properties for each class in the mdc.
            var mdc = domainObjectDtoRepository.MDC;
            var cachedBasicProperties = CacheBasicProperties(mdc);

            foreach (var kvp in cachedBasicProperties)
            {
                var className = kvp.Key;
                if (mdc.GetAbstract(mdc.GetClassId(className)))
                {
                    continue;                     // Won't find any of those as dtos.
                }
                var basicProps = kvp.Value;
                foreach (var dto in domainObjectDtoRepository.AllInstancesSansSubclasses(className))
                {
                    var rootElementChanged = false;
                    var rootElement        = XElement.Parse(dto.Xml);
                    foreach (var basicPropertyInfo in basicProps)
                    {
                        if (basicPropertyInfo.m_isCustom)
                        {
                            var customPropElement = rootElement.Elements("Custom").FirstOrDefault(element => element.Attribute("name").Value == basicPropertyInfo.m_propertyName);
                            if (customPropElement == null)
                            {
                                CreateCustomProperty(rootElement, basicPropertyInfo);
                                rootElementChanged = true;
                            }
                        }
                        else
                        {
                            var basicPropertyElement = rootElement.Element(basicPropertyInfo.m_propertyName);
                            if (basicPropertyElement == null && !SkipTheseBasicPropertyNames.Contains(basicPropertyInfo.m_propertyName) && !basicPropertyInfo.m_isVirtual)
                            {
                                CreateBasicProperty(rootElement, basicPropertyInfo);
                                rootElementChanged = true;
                            }
                        }
                    }
                    if (!rootElementChanged)
                    {
                        continue;
                    }

                    dto.Xml = rootElement.ToString();
                    domainObjectDtoRepository.Update(dto);
                }
            }

            DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
        }
Example #48
0
 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);
     }
 }
		public void PerformMigration(IDomainObjectDTORepository repoDto)
		{
			DataMigrationServices.CheckVersionNumber(repoDto, 7000041);

			var dtoLexDb = repoDto.AllInstancesSansSubclasses("LexDb").First();
			var xeLexDb = XElement.Parse(dtoLexDb.Xml);
			var guidComplexTypes = GetGuidValue(xeLexDb, "ComplexEntryTypes/objsur");
			var guidVariantTypes = GetGuidValue(xeLexDb, "VariantEntryTypes/objsur");
			BuildStandardMaps(guidComplexTypes, guidVariantTypes);
			var extraTypes = new List<LexTypeInfo>();
			var unprotectedTypes = new List<LexTypeInfo>();
			foreach (var dto in repoDto.AllInstancesSansSubclasses("LexEntryType"))
			{
				var xeType = XElement.Parse(dto.Xml);
				// ReSharper disable PossibleNullReferenceException
				var guid = xeType.Attribute("guid").Value;
				// ReSharper restore PossibleNullReferenceException
				string name;
				if (m_mapGuidName.TryGetValue(guid, out name))
				{
					m_mapGuidName.Remove(guid);
					m_mapNameGuid.Remove(name);
					var xeProt = xeType.XPathSelectElement("IsProtected");
					if (xeProt == null)
					{
						unprotectedTypes.Add(new LexTypeInfo(dto, xeType));
					}
					else
					{
						var xaVal = xeProt.Attribute("val");
						if (xaVal == null || xaVal.Value.ToLowerInvariant() != "true")
							unprotectedTypes.Add(new LexTypeInfo(dto, xeType));
					}
				}
				else
				{
					extraTypes.Add(new LexTypeInfo(dto, xeType));
				}
			}
			foreach (var info in unprotectedTypes)
			{
				var xeProt = info.XmlElement.XPathSelectElement("IsProtected");
				if (xeProt != null)
					xeProt.Remove();
				info.XmlElement.Add(new XElement("IsProtected", new XAttribute("val", "true")));
				info.DTO.Xml = info.XmlElement.ToString();
				repoDto.Update(info.DTO);
			}
			if (m_mapGuidName.Count > 0)
				FixOrAddMissingTypes(repoDto, extraTypes);
			FixOwnershipOfSubtypes(repoDto);
			DataMigrationServices.IncrementVersionNumber(repoDto);
		}
        /// <summary>
        /// If user created a Custom "Exemplar" or "UsageNote" of type MultiString or MultiUnicode,
        /// copy that data into the new built-in MultiString element and, if MultiString, remove the Custom Field.
        /// If a conflicting Custom Field cannot be migrated and removed, rename it to avoid conflict.
        /// </summary>
        internal static void MigrateIntoNewMultistringField(IDomainObjectDTORepository repoDto, string fieldName)
        {
            // This is the same algorithm used by FDOBackendProvider.PreLoadCustomFields to prevent naming conflicts with existing Custom Fields
            var nameSuffix   = 0;
            var lexSenseClid = repoDto.MDC.GetClassId("LexSense");

            while (repoDto.MDC.FieldExists(lexSenseClid, fieldName + nameSuffix, false))
            {
                ++nameSuffix;
            }
            var newFieldName = fieldName + nameSuffix;

            foreach (var dto in repoDto.AllInstancesSansSubclasses("LexSense"))
            {
                var data = XElement.Parse(dto.Xml);

                var customElt = data.Elements("Custom").FirstOrDefault(elt => elt.Attribute("name").Value == fieldName);
                if (customElt == null)
                {
                    continue;
                }
                customElt.SetAttributeValue("name", newFieldName);                 // rename to the new custom Exemplar name

                var builtInElt     = new XElement(fieldName);
                var isFieldBuiltIn = false;
                foreach (var multiStrElt in customElt.Elements("AStr"))
                {
                    builtInElt.Add(multiStrElt);
                    isFieldBuiltIn = true;
                }
                foreach (var multiStrElt in customElt.Elements("AUni"))
                {
                    multiStrElt.Name = "AStr";
                    var mutiStrData = multiStrElt.Value;
                    multiStrElt.Value = string.Empty;
                    var wsAttr = multiStrElt.Attribute("ws");
                    var runElt = new XElement("Run")
                    {
                        Value = mutiStrData
                    };
                    runElt.SetAttributeValue("ws", wsAttr.Value);
                    multiStrElt.Add(runElt);
                    builtInElt.Add(multiStrElt);
                    isFieldBuiltIn = true;
                }
                if (isFieldBuiltIn)
                {
                    customElt.Remove();
                    data.Add(builtInElt);
                }
                DataMigrationServices.UpdateDTO(repoDto, dto, data.ToString());
            }
        }
        /// <summary>
        /// Change LexEntry.Etymology to Owned Sequence, add several fields to LexEtymology
        /// Change some existing field signatures. Remove Source and put its data in LanguageNotes
        /// in a slightly different format (Unicode -> MultiString). Also add a new list Languages
        /// owned by LexDb. Languages list will be initially empty.
        /// </summary>
        /// <remarks>internal for testing</remarks>
        internal static void AugmentEtymologyCluster(IDomainObjectDTORepository repoDto)
        {
            const string languagesListGuid = "487c15b0-2ced-4417-8b77-9075f4a21e5f";
            var          lexDbDTO          = repoDto.AllInstancesSansSubclasses("LexDb").FirstOrDefault();

            if (lexDbDTO == null)
            {
                return;                 // This must be a test that doesn't care about LexDb.
            }
            var lexDbElt = XElement.Parse(lexDbDTO.Xml);

            CreateNewLexDbProperty(lexDbElt, "Languages", languagesListGuid);
            var lexDbGuid = lexDbElt.Attribute("guid").Value;

            // create Languages' possibility list
            DataMigrationServices.CreatePossibilityList(repoDto, languagesListGuid, lexDbGuid,
                                                        new[]
            {
                new Tuple <string, string, string>("en", "Lgs", "Languages"),
                new Tuple <string, string, string>("fr", "Lgs", "Langues"),
                new Tuple <string, string, string>("es", "Ids", "Idiomas")
            },
                                                        new DateTime(2016, 7, 25, 18, 48, 18), WritingSystemServices.kwsAnals);
            DataMigrationServices.UpdateDTO(repoDto, lexDbDTO, lexDbElt.ToString());             // update LexDb object

            // Augment existing Etymologies
            var etymologyDtos = repoDto.AllInstancesSansSubclasses("LexEtymology");

            if (!etymologyDtos.Any())
            {
                return;
            }
            var primaryAnalysisWs = ExtractPrimaryWsFromLangProj(repoDto, true);

            foreach (var etymologyDto in etymologyDtos)
            {
                ChangeMultiUnicodeElementToMultiString(repoDto, etymologyDto, "//Form");
                ChangeMultiUnicodeElementToMultiString(repoDto, etymologyDto, "//Gloss");
                var dataElt   = XElement.Parse(etymologyDto.Xml);
                var sourceElt = dataElt.Element("Source");
                if (sourceElt == null)
                {
                    continue;
                }
                sourceElt.Name = "LanguageNotes";                 // sourceElt is now the languageNotesElt!
                var oldSourceData = sourceElt.Element("Uni").Value;
                var multiStrElt   = BuildMultiStringElement(primaryAnalysisWs, oldSourceData);
                sourceElt.RemoveAll();
                sourceElt.Add(multiStrElt);
                DataMigrationServices.UpdateDTO(repoDto, etymologyDto, dataElt.ToString());
            }
        }
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000057);
			{
				// LT-13312 Note some projects may not have these guids.
				DomainObjectDTO dtoVariantType;
				if (domainObjectDtoRepository.TryGetValue(LexEntryTypeTags.kguidLexTypPluralVar.ToString(), out dtoVariantType))
					AddGlossAppendIfEmpty(domainObjectDtoRepository, dtoVariantType, ".pl");
				if (domainObjectDtoRepository.TryGetValue(LexEntryTypeTags.kguidLexTypPastVar.ToString(), out dtoVariantType))
					AddGlossAppendIfEmpty(domainObjectDtoRepository, dtoVariantType, ".pst");
			}
			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Change all guids to lowercase to help the Chorus diff/merge code.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000022);

			foreach (var dto in domainObjectDtoRepository.AllInstancesWithValidClasses())
			{
				var rtElement = XElement.Parse(dto.Xml);
				if (ShiftCase(rtElement))
					DataMigrationServices.UpdateDTO(domainObjectDtoRepository, dto, rtElement.ToString());
			}

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
        internal static void RemoveEmptyLexEntryRefs(IDomainObjectDTORepository repoDto)
        {
            foreach (var dto in repoDto.AllInstancesWithSubclasses("LexEntryRef"))
            {
                XElement data = XElement.Parse(dto.Xml);

                var components = data.Element("ComponentLexemes");
                if (components == null || !components.HasElements)
                {
                    DataMigrationServices.RemoveIncludingOwnedObjects(repoDto, dto, true);
                }
            }
        }
Example #55
0
        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());
        }
Example #56
0
        public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
        {
            DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000051);

            var          newGuidValue = Guid.NewGuid().ToString().ToLowerInvariant();
            const string className    = "WfiMorphBundle";
            var          wmbList      = domainObjectDtoRepository.AllInstancesSansSubclasses(className);

            foreach (var wmb in wmbList)
            {
                XElement wmbElt   = XElement.Parse(wmb.Xml);
                var      morphElt = wmbElt.Element("Morph");
                // if we don't have a morph reference,
                // then there's nothing to copy into the form field.
                if (morphElt == null)
                {
                    continue;
                }
                var objsurElt      = morphElt.Element("objsur");
                var dtoMorphTarget = domainObjectDtoRepository.GetDTO(objsurElt.Attribute("guid").Value);
                // for each form alternative, copy the writing system

                // if for some reason there is a morphbundle form that already exists, delete it before inserting another.
                var formElt = wmbElt.Element("Form");
                if (formElt != null)
                {
                    formElt.Remove();
                }

                var morphTargetElt     = XElement.Parse(dtoMorphTarget.Xml);
                var morphTargetFormElt = morphTargetElt.Element("Form");
                if (morphTargetFormElt == null)
                {
                    continue;
                }
                formElt = XElement.Parse("<Form/>");
                wmbElt.AddFirst(formElt);
                foreach (var aUniElt in morphTargetFormElt.Elements("AUni"))
                {
                    string ws            = aUniElt.Attribute("ws").Value;
                    string form          = aUniElt.Value;
                    var    newFormAltElt = XElement.Parse(String.Format("<AStr ws=\"{0}\"/>", ws));
                    formElt.Add(newFormAltElt);
                    var newRunElt = XElement.Parse(String.Format("<Run ws=\"{0}\">{1}</Run>", ws, XmlUtils.MakeSafeXml(form)));
                    newFormAltElt.Add(newRunElt);
                }
                DataMigrationServices.UpdateDTO(domainObjectDtoRepository, wmb, wmbElt.ToString());
            }

            DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Sets the ParaContainingOrc property for all ScrFootnotes
        /// </summary>
        /// <param name="domainObjectDtoRepository">
        /// Repository of all CmObject DTOs available for one migration step.
        /// </param>
        /// <remarks>
        /// The method must add/remove/update the DTOs to the repository,
        /// as it adds/removes objects as part of it work.
        ///
        /// Implementors of this interface should ensure the Repository's
        /// starting model version number is correct for the step.
        /// Implementors must also increment the Repository's model version number
        /// at the end of its migration work.
        ///
        /// The method also should normally modify the xml string(s)
        /// of relevant DTOs, since that string will be used by the main
        /// data migration calling client (ie. BEP).
        /// </remarks>
        /// ------------------------------------------------------------------------------------
        public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
        {
            DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000026);

            foreach (var scrTxtPara in domainObjectDtoRepository.AllInstancesSansSubclasses("ScrTxtPara"))
            {
                XElement para     = XElement.Parse(scrTxtPara.Xml);
                XElement contents = para.Element("Contents");
                if (contents == null)
                {
                    continue;
                }
                XElement str = contents.Element("Str");
                if (str == null)
                {
                    continue;
                }

                foreach (XElement run in str.Elements("Run"))
                {
                    XAttribute linkAttr = run.Attribute("ownlink");
                    if (linkAttr == null)
                    {
                        continue;                         // Run doesn't contain a link
                    }
                    DomainObjectDTO linkObj;
                    // skip links to missing footnotes - user will have to clean these up later.
                    if (!domainObjectDtoRepository.TryGetValue(linkAttr.Value, out linkObj))
                    {
                        continue;
                    }
                    XElement footnote = XElement.Parse(linkObj.Xml);
                    if (footnote.Attribute("class").Value != "ScrFootnote")
                    {
                        continue;                         // Link is not for a footnote
                    }
                    if (footnote.Element("ParaContainingOrc") == null)
                    {
                        // ParaContainingOrc property is not present in the footnote, so it needs
                        // to be added.
                        XElement paraContainingOrcElm = XElement.Parse("<ParaContainingOrc><objsur guid=\"" +
                                                                       scrTxtPara.Guid + "\" t=\"r\" /></ParaContainingOrc>");
                        footnote.Add(paraContainingOrcElm);

                        DataMigrationServices.UpdateDTO(domainObjectDtoRepository, linkObj, footnote.ToString());
                    }
                }
            }

            DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
        }
		/// <summary>
		/// Check to see if there is any data in RnGenericRec.Weather fields.  If not, delete
		/// the field and list. If there is, convert the Weather field into a custom field and
		/// the Weather list into a custom list.
		/// </summary>
		public void PerformMigration(IDomainObjectDTORepository repoDTO)
		{
			var collectOverlaysToRemove = new List<DomainObjectDTO>();
			bool fWeatherUsed = IsWeatherUsed(repoDTO, collectOverlaysToRemove);
			if (fWeatherUsed)
				ConvertWeatherToCustomListAndField(repoDTO);
			else
			{
				DeleteWeatherListAndField(repoDTO);
				RemoveUnwantedOverlays(repoDTO, collectOverlaysToRemove);
			}

			DataMigrationServices.IncrementVersionNumber(repoDTO);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// locate all files in %appdata%/SIL/FieldWorks/Language Explorer/db$projectname$*.* and move them
		/// to projects/projectname/ConfigurationSettings/db$local$*.*
		/// </summary>
		/// <param name="repoDto">
		/// Repository of all CmObject DTOs available for one migration step.
		/// </param>
		/// <remarks>
		/// Implementors of this interface should ensure the Repository's
		/// starting model version number is correct for the step.
		/// Implementors must also increment the Repository's model version number
		/// at the end of its migration work.
		///
		/// The method also should normally modify the xml string(s)
		/// of relevant DTOs, since that string will be used by the main
		/// data migration calling client (ie. BEP).
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public void PerformMigration(IDomainObjectDTORepository repoDto)
		{
			DataMigrationServices.CheckVersionNumber(repoDto, 7000031);
			var projectFolder = repoDto.ProjectFolder;
			var projectName = Path.GetFileNameWithoutExtension(projectFolder);
			// This is equivalent to DirectoryFinder.UserAppDataFolder("Language Explorer") at the time of creating
			// the migration, but could conceivably change later.
			var sourceDir = Path.Combine(
				Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SIL"),
				"Language Explorer");
			// This is equivalent to DirectoryFinder.GetConfigSettingsDir(projectFolder) at the time of creating
			// the migration, but could conceivably change later.
			var targetDir = Path.Combine(projectFolder, "ConfigurationSettings");
			if (Directory.Exists(sourceDir))
			{
				Directory.CreateDirectory(targetDir);
				string oldPrefix = "db$" + projectName + "$";
				const string newPrefix = "db$local$";
				foreach (var path in Directory.GetFiles(sourceDir, oldPrefix + "*.*"))
				{
					var filename = Path.GetFileName(path);
					if (filename == null)
						continue;
					var targetName = filename.Substring(oldPrefix.Length);
					if (targetName.ToLowerInvariant() == "settings.xml")
					{
						targetName = newPrefix + targetName;
						var destFileName1 = Path.Combine(targetDir, targetName);
						if (!File.Exists(destFileName1))
						{
							// The settings file contains saved properties that begin with db$ProjectName$ and need to be db$Local$
							using (var reader = new StreamReader(path, Encoding.UTF8))
							{
								using (var writer = FileUtils.OpenFileForWrite(destFileName1, Encoding.UTF8))
								{
									while (!reader.EndOfStream)
										writer.WriteLine(reader.ReadLine().Replace(oldPrefix, newPrefix));
								}
							}
						}
					}
					var destFileName = Path.Combine(targetDir, targetName);
					if (!File.Exists(destFileName))
						File.Copy(path, destFileName);
				}
			}

			DataMigrationServices.IncrementVersionNumber(repoDto);
		}
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000065);

			// Cache all basic data properties for each class in the mdc.
			var mdc = domainObjectDtoRepository.MDC;
			var cachedBasicProperties = CacheBasicProperties(mdc);
			foreach (var kvp in cachedBasicProperties)
			{
				var className = kvp.Key;
				if (mdc.GetAbstract(mdc.GetClassId(className)))
					continue; // Won't find any of those as dtos.

				var basicProps = kvp.Value;
				foreach (var dto in domainObjectDtoRepository.AllInstancesSansSubclasses(className))
				{
					var rootElementChanged = false;
					var rootElement = XElement.Parse(dto.Xml);
					foreach (var basicPropertyInfo in basicProps)
					{
						if (basicPropertyInfo.m_isCustom)
						{
							var customPropElement = rootElement.Elements("Custom").FirstOrDefault(element => element.Attribute("name").Value == basicPropertyInfo.m_propertyName);
							if (customPropElement == null)
							{
								CreateCustomProperty(rootElement, basicPropertyInfo);
								rootElementChanged = true;
							}
						}
						else
						{
							var basicPropertyElement = rootElement.Element(basicPropertyInfo.m_propertyName);
							if (basicPropertyElement == null && !SkipTheseBasicPropertyNames.Contains(basicPropertyInfo.m_propertyName) && !basicPropertyInfo.m_isVirtual)
							{
								CreateBasicProperty(rootElement, basicPropertyInfo);
								rootElementChanged = true;
							}
						}
					}
					if (!rootElementChanged)
						continue;

					dto.Xml = rootElement.ToString();
					domainObjectDtoRepository.Update(dto);
				}
			}

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}