Пример #1
0
		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);
		}
Пример #2
0
        /// <summary>
        /// Creates a CmPossibility with all the basic properties filled in for the xml (necessary for S/R) and adds it to the dto
        /// </summary>
        public static DomainObjectDTO CreatePossibility(IDomainObjectDTORepository repoDto, string listGuid, string possibilityGuid, string name,
                                                        string abbr, DateTime createTime, string className = "CmPossibility")
        {
            var sb = new StringBuilder();

            sb.AppendFormat("<rt class=\"{0}\" guid=\"{1}\" ownerguid=\"{2}\">", className, possibilityGuid, listGuid);
            sb.Append("<Abbreviation>");
            sb.AppendFormat("<AUni ws=\"en\">{0}</AUni>", abbr);
            sb.Append("</Abbreviation>");
            sb.Append(string.Format("<DateCreated val=\"{0:yyyy-MM-dd HH:mm:ss.fff}\" />", createTime));
            sb.Append(string.Format("<DateModified val=\"{0:yyyy-MM-dd HH:mm:ss.fff}\" />", createTime));
            sb.Append("<BackColor val=\"-1073741824\" />");
            sb.Append("<ForeColor val=\"-1073741824\" />");
            sb.Append("<IsProtected val=\"True\" />");
            sb.Append("<Hidden val=\"False\" />");
            sb.Append("<Name>");
            sb.AppendFormat("<AUni ws=\"en\">{0}</AUni>", name);
            sb.Append("</Name>");
            sb.Append("<SortSpec val=\"-1073741824\" />");
            sb.Append("<UnderColor val=\"-1073741824\" />");
            sb.Append("<UnderStyle val=\"-1073741824\" />");
            sb.Append("</rt>");
            var dtoCmPossibility = new DomainObjectDTO(possibilityGuid, className, sb.ToString());

            repoDto.Add(dtoCmPossibility);
            return(dtoCmPossibility);
        }
        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);
        }
Пример #4
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);
        }
Пример #5
0
        // Make a new CmFile element for the specified path, and an objsur child of langCmFolder to own it.
        // In this migration a typical result would be:
        //    <rt guid="c4f4760e-049e-49af-ac57-73c686100700" class="CmFile" ownerguid="3e615e09-3b86-4fae-adfe-5fc2473214b6">
        //    <InternalPath>
        //        <Uni>C:\FwWW\DistFiles\AudioVisual\NotInLinkedFilesPath.WMV</Uni>
        //    </InternalPath>
        //    </rt>
        private void MakeCmFile(IDomainObjectDTORepository domainObjectDtoRepository, string langCmFolderGuid,
                                XElement langCmFolder, string path)
        {
            string cmFileGuid;

            cmFileGuid = Guid.NewGuid().ToString();
            var cmFileXElement = new XElement("rt",
                                              new XAttribute("guid", cmFileGuid),
                                              new XAttribute("class", "CmFile"),
                                              new XAttribute("ownerguid", langCmFolderGuid),
                                              MakeUnicode("InternalPath", path));
            var dtoConfirmed = new DomainObjectDTO(cmFileGuid, "CmFile", cmFileXElement.ToString());

            domainObjectDtoRepository.Add(dtoConfirmed);
            langCmFolder.Element("Files").Add(MakeOwningSurrogate(cmFileGuid));
        }
Пример #6
0
		private static DomainObjectDTO MakeEvaluation(string ownerGuid, IDomainObjectDTORepository domainObjectDtoRepository, XElement agentElement, string owningAttr)
		{
			var newGuid = Guid.NewGuid().ToString().ToLower();
			var newEvalElt = new XElement("rt",
				new XAttribute("class", "CmAgentEvaluation"),
				new XAttribute("guid", newGuid),
				new XAttribute("ownerguid", ownerGuid),
				new XElement("CmObject"),
				new XElement("CmAgentEvaluation"));
			// Create new dto and add to repos.
			var newEval = new DomainObjectDTO(newGuid, "CmAgentEvaluation", newEvalElt.ToString());
			domainObjectDtoRepository.Add(newEval);
			agentElement.Add(new XElement(owningAttr,
				new XElement("objsur", new XAttribute("t", "o"), new XAttribute("guid", newGuid))));

			return newEval;
		}
Пример #7
0
        private string MakeStatus(IDomainObjectDTORepository domainObjectDtoRepository, string langPossListGuid,
                                  XElement langPossListElement, string name, string abbr)
        {
            string statusConfirmedGuid;

            statusConfirmedGuid = Guid.NewGuid().ToString();
            var confirmed = new XElement("rt",
                                         new XAttribute("class", "CmPossibility"),
                                         new XAttribute("guid", statusConfirmedGuid),
                                         new XAttribute("ownerguid", langPossListGuid),
                                         MakeMultiUnicode("Name", name),
                                         MakeMultiUnicode("Abbreviation", abbr));
            var dtoConfirmed = new DomainObjectDTO(statusConfirmedGuid, "CmPossibility", confirmed.ToString());

            domainObjectDtoRepository.Add(dtoConfirmed);
            langPossListElement.Element("Possibilities").Add(MakeOwningSurrogate(statusConfirmedGuid));
            return(statusConfirmedGuid);
        }
Пример #8
0
        // Creates a CmFolder whose owning guid is the langProjectGuid passed as a child of the element passed
        // and gives it the name passed. In this migration a typical result (after later code adds the Files) would be:
        // <rt guid="3e615e09-3b86-4fae-adfe-5fc2473214b6" class="CmFolder" ownerguid="b8bdad3d-9006-46f0-83e8-ae1d1726f2ad">
        //    <Name>
        //        <AUni ws="pt">File paths in TsStrings</AUni>
        //    </Name>
        //    <Files>
        //        <objsur guid="c4f3760e-049e-49af-ac57-73c686100700" t="o" />
        //        <objsur guid="c4f4760e-049e-49af-ac57-73c686100700" t="o" />
        //    </Files>
        //</rt>
        private XElement MakeCmFolder(IDomainObjectDTORepository domainObjectDtoRepository, string langProjectGuid,
                                      XElement filePathsInTsStringsCmFolder, string name, out DomainObjectDTO folderDto)
        {
            string cmFolderGuid;

            cmFolderGuid = Guid.NewGuid().ToString();
            var cmFolderXML = new XElement("rt",
                                           new XAttribute("guid", cmFolderGuid),
                                           new XAttribute("class", "CmFolder"),
                                           new XAttribute("ownerguid", langProjectGuid),
                                           MakeMultiUnicode("Name", name),
                                           new XElement("Files"));

            folderDto = new DomainObjectDTO(cmFolderGuid, "CmFolder", cmFolderXML.ToString());
            domainObjectDtoRepository.Add(folderDto);
            filePathsInTsStringsCmFolder.Add(MakeOwningSurrogate(cmFolderGuid));
            return(cmFolderXML);
        }
Пример #9
0
        /// <summary>
        /// Changes the GUID of the specified DTO. It updates the owner and all specified referrers to point to the new GUID.
        /// </summary>
        /// <param name="dtoRepos">The dto repos.</param>
        /// <param name="dto">The dto.</param>
        /// <param name="newGuid">The new GUID.</param>
        /// <param name="possibleReferrers">The possible referrers.</param>
        internal static void ChangeGuid(IDomainObjectDTORepository dtoRepos, DomainObjectDTO dto, string newGuid,
                                        IEnumerable <DomainObjectDTO> possibleReferrers)
        {
            // if the DTO already has the new GUID, don't do anything
            if (dto.Guid.ToLowerInvariant() == newGuid.ToLowerInvariant())
            {
                return;
            }

            XElement rtElem = XElement.Parse(dto.Xml);

            rtElem.Attribute("guid").Value = newGuid;
            dtoRepos.Add(new DomainObjectDTO(newGuid, dto.Classname, rtElem.ToString()));
            foreach (DomainObjectDTO ownedDto in dtoRepos.GetDirectlyOwnedDTOs(dto.Guid))
            {
                XElement ownedElem = XElement.Parse(ownedDto.Xml);
                ownedElem.Attribute("ownerguid").Value = newGuid;
                UpdateDTO(dtoRepos, ownedDto, ownedElem.ToString());
            }

            var ownerDto = dtoRepos.GetOwningDTO(dto);

            if (ownerDto != null)
            {
                UpdateObjSurElement(dtoRepos, ownerDto, dto.Guid, newGuid);
            }

            if (possibleReferrers != null)
            {
                foreach (DomainObjectDTO referrer in possibleReferrers)
                {
                    UpdateObjSurElement(dtoRepos, referrer, dto.Guid, newGuid);
                }
            }
            dtoRepos.Remove(dto);
        }
Пример #10
0
		private void FixOrAddMissingTypes(IDomainObjectDTORepository repoDto, IEnumerable<LexTypeInfo> extraTypes)
		{
			foreach (var info in extraTypes)
			{
				var fChanged = false;
				foreach (var xeAUni in info.XmlElement.XPathSelectElements("Name/AUni"))
				{
					var xaWs = xeAUni.Attribute("ws");
					if (xaWs == null || xaWs.Value.ToLowerInvariant() != "en")
						continue;
					var name = xeAUni.Value;
					string guidStd;
					if (!m_mapNameGuid.TryGetValue(name, out guidStd))
						continue;
					// We need to change the guid of this dto from 'guid to 'guidStd
					ChangeInvalidGuid(repoDto, info, name, guidStd);
				}
				var xeProt = info.XmlElement.XPathSelectElement("IsProtected");
				if (xeProt == null)
				{
					info.XmlElement.Add(new XElement("IsProtected", new XAttribute("val", "true")));
					fChanged = true;
				}
				else
				{
					var xaVal = xeProt.Attribute("val");
					if (xaVal == null)
					{
						xeProt.Add(new XAttribute("val", "true"));
						fChanged = true;
					}
					else if (xaVal.Value.ToLowerInvariant() != "true")
					{
						xaVal.SetValue("true");
						fChanged = true;
					}
				}
				if (fChanged)
				{
					info.DTO.Xml = info.XmlElement.ToString();
					repoDto.Update(info.DTO);
				}
			}

			if (m_mapNameGuid.Count > 0)
			{
				BuildNewTypeMaps();
				var newTypes = new HashSet<DomainObjectDTO>();
				foreach (var guid in m_mapGuidName.Keys)
				{
					// We need to create this LexEntryType!
					var rgNewDtos = m_mapGuidNewDtos[guid];
					foreach (var info in rgNewDtos)
					{
						var dto = new DomainObjectDTO(info.Guid, info.ClassName, info.Xml);
						repoDto.Add(dto);
						if (info.ClassName == "LexEntryType")
							newTypes.Add(dto);

					}
				}
				foreach (var dto in newTypes)
				{
					var dtoOwner = repoDto.GetOwningDTO(dto);
					var xeOwner = XElement.Parse(dtoOwner.Xml);
					XElement xePoss = null;
					if (dtoOwner.Classname == "CmPossibilityList")
					{
						xePoss = xeOwner.Element("Possibilities");
						if (xePoss == null)
						{
							xePoss = new XElement("Possibilities");
							xeOwner.Add(xePoss);
						}
					}
					else if (dtoOwner.Classname == "LexEntryType")
					{
						xePoss = xeOwner.Element("SubPossibilities");
						if (xePoss == null)
						{
							xePoss = new XElement("SubPossibilities");
							xeOwner.Add(xePoss);
						}
					}
					if (xePoss != null)
					{
						var fNeeded = true;
						foreach (var objsur in xePoss.Elements("objsur"))
						{
							var xaGuid = objsur.Attribute("guid");
							if (xaGuid == null)
								throw new Exception("missing guid in an objsur element");
							if (xaGuid.Value.Equals(dto.Guid, StringComparison.OrdinalIgnoreCase))
							{
								fNeeded = false;
								break;
							}
						}
						if (fNeeded)
						{
							xePoss.Add(DataMigrationServices.CreateOwningObjSurElement(dto.Guid));
							dtoOwner.Xml = xeOwner.ToString();
							repoDto.Update(dtoOwner);
						}
					}
				}
			}
		}
Пример #11
0
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000040);

			// (WRONG) The ExcludeAsHeadword element only appears when @val="true" and
			// it is to be replaced by DoNotShowMainEntryIn with a list of all publications.
			// NB: The above statement is simply not true (RBR).
			// FW 7 writes out all primitive data properties.
			// The FW 6-FW7 migrator doesn't add them,
			// but FW 7 writes them the next time an object gets changed.

			// Make the list of publications once
			var newElt = new XElement("DoNotShowMainEntryIn");

			IEnumerable<XElement> dtoPubList = null;
			// XPATH: rt[Name/AUni='Publications']/Possibilities/objsur
			foreach (var a_list in domainObjectDtoRepository.AllInstancesSansSubclasses("CmPossibilityList"))
			{
				var xList = XElement.Parse(a_list.Xml);
				if (xList.XPathSelectElement("Name[AUni='Publications']") == null) continue;
				dtoPubList = xList.XPathSelectElements("Possibilities/objsur");
				if (dtoPubList != null && dtoPubList.Count() > 0) break;
			}

			if (dtoPubList == null || dtoPubList.Count() == 0) // add the Publications list to the project
			{   // This list is owned by LexDb
				var ieDtoLexDb = domainObjectDtoRepository.AllInstancesSansSubclasses("LexDb");
				Debug.Assert(ieDtoLexDb != null && ieDtoLexDb.Count<DomainObjectDTO>() == 1, "Project has no LexDb Dto or more than one");
				var dtoLexDb = ieDtoLexDb.First<DomainObjectDTO>();
				var xNode = XElement.Parse(dtoLexDb.Xml);
				var ksguidLexDb = xNode.Attribute("guid").Value;
				var nowStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
				string xmlStrPub =
"<rt guid=\"" + ksguidPubList + "\" class=\"CmPossibilityList\" ownerguid=\"" + ksguidLexDb + "\"><Name><AUni ws=\"en\">Publications</AUni></Name><DateCreated val=\"" + nowStr + "\" /><DateModified val=\"" + nowStr + "\" /><Depth val=\"1\" /><PreventChoiceAboveLevel val=\"0\" /><IsSorted val=\"True\" /><IsClosed val=\"False\" /><PreventDuplicates val=\"False\" /><PreventNodeChoices val=\"False\" /><UseExtendedFields val=\"False\" /><DisplayOption val=\"0\" /><ItemClsid val=\"7\" /><IsVernacular val=\"False\" /><WsSelector val=\"0\" /><ListVersion val=\"00000000-0000-0000-0000-000000000000\" /><Possibilities><objsur guid=\"" + ksguidMainDictionary + "\" t=\"o\" /></Possibilities></rt>";
				var dtoPub = new DomainObjectDTO(ksguidPubList, "CmPossibilityList", xmlStrPub);

				string xmlStrMD = "<rt guid=\"" + ksguidMainDictionary + "\" class=\"CmPossibility\" ownerguid=\"" + ksguidPubList + "\"><Name><AUni ws=\"en\">Main Dictionary</AUni></Name><Abbreviation><AUni ws=\"en\">Main</AUni></Abbreviation><SortSpec val=\"0\" /><DateCreated val=\"" + nowStr + "\" /><DateModified val=\"" + nowStr + "\" /><ForeColor val=\"0\" /><BackColor val=\"0\" /><UnderColor val=\"0\" /><UnderStyle val=\"0\" /><Hidden val=\"False\" /><IsProtected val=\"True\" /></rt>";
				var dtoMD = new DomainObjectDTO(ksguidMainDictionary, "CmPossibility", xmlStrMD);

				domainObjectDtoRepository.Add(dtoMD);
				domainObjectDtoRepository.Add(dtoPub);

				// Make xLexDb own dtoPub
				var xPts = xNode.Element("PublicationTypes");
				if (xPts == null)
				{   // add one to LexDb
					xPts = new XElement("PublicationTypes");
					xPts.Add(DataMigrationServices.CreateOwningObjSurElement(ksguidPubList));
					xNode.Add(xPts);
				}
				Debug.Assert(xPts != null, "LexDb has no PublicatonTypes and won't accept new ones.");
				dtoLexDb.Xml = xNode.ToString();
				domainObjectDtoRepository.Update(dtoLexDb);
				newElt.Add(DataMigrationServices.CreateReferenceObjSurElement(ksguidMainDictionary));
			}
			else
			{   // already had a publications list - add all to DoNotShowMainEntryIn
				foreach (var xElt in dtoPubList)
				{   // change the t attr to "r" reference instead of "o" own.
					var xPubRef = new XElement(xElt);
					xPubRef.SetAttributeValue("t", "r");
					newElt.Add(xPubRef);
				}
			}
			foreach (var dto in domainObjectDtoRepository.AllInstancesSansSubclasses("LexEntry"))
			{
				// (WRONG) The ExcludeAsHeadword element only appears when @val="true" unless played with in a text editor
				// NB: The above statement is simply not true (RBR).
				// FW 7 writes out all primitive data properties.
				// The FW 6-FW7 migrator doesn't add them,
				// but FW 7 writes them the next time an object gets changed.
				var xElt = XElement.Parse(dto.Xml);
				var exHeadword = xElt.Element("ExcludeAsHeadword");
				if (exHeadword == null)
					continue;
				XAttribute XAval = exHeadword.Attribute("val");
				// It must be upper-case, since that is what is output.
				if (XAval.Value == "True")
				{	// Add all publications from the list to this property
					xElt.Add(new XElement(newElt));
				}
				exHeadword.Remove(); // exHeadword.Value may be True, False or invalid
				dto.Xml = xElt.ToString();
				domainObjectDtoRepository.Update(dto);
			}
			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
Пример #12
0
		private string MakeStatus(IDomainObjectDTORepository domainObjectDtoRepository, string langPossListGuid,
			XElement langPossListElement, string name, string abbr)
		{
			string statusConfirmedGuid;
			statusConfirmedGuid = Guid.NewGuid().ToString();
			var confirmed = new XElement("rt",
										 new XAttribute("class", "CmPossibility"),
										 new XAttribute("guid", statusConfirmedGuid),
										 new XAttribute("ownerguid", langPossListGuid),
										 MakeMultiUnicode("Name", name),
										 MakeMultiUnicode("Abbreviation", abbr));
			var dtoConfirmed = new DomainObjectDTO(statusConfirmedGuid, "CmPossibility", confirmed.ToString());
			domainObjectDtoRepository.Add(dtoConfirmed);
			langPossListElement.Element("Possibilities").Add(MakeOwningSurrogate(statusConfirmedGuid));
			return statusConfirmedGuid;
		}
Пример #13
0
		private static List<KeyValuePair<byte[], XElement>> ProcessDiscourseData(IDomainObjectDTORepository dtoRepos,
			IDictionary<string, SortedList<int, byte[]>> paraToOldSegments,
			IEnumerable<byte[]> oldCCRs,
			IDictionary<string, byte[]> oldCCAs,
			IDictionary<Guid, Guid> ccaGuidMap) // Key is old CCA guid. Value is new CCA guid.
		{
			// Make a mapping between old CCA anns and new ConstChartWordGroup objects (both XElements),
			// which are the ones where the old ann had twfics in AppliesTo.
			// These will be fed into the code that converts the twfics,
			// so as to have access to the right conversion context
			// (i.e., be able to get at the Segment and start/end indices for the twfics).
			var halfBakedCcwgItems = new List<KeyValuePair<byte[], XElement>>();

			// Map between old CCR ann guid and new CCR guid, so code in here can keep track of them.
			// Key is the original CCR guid. Value is the new CCR guid.
			//var ccrRowsGuidMap = new Dictionary<string, string>();
			// Key is the new CCR guid. Value is the guid of its new owning chart.
			var ccrOwnerGuidMap = new Dictionary<Guid, Guid>();

			// Migrate the DsConstChart(s).
			foreach (var chartDto in dtoRepos.AllInstancesSansSubclasses("DsConstChart"))
			{
				var chartElement = XElement.Parse(chartDto.Xml);

				foreach (var objsurElement in chartElement.Element("DsConstChart").Elements("Rows").Elements("objsur"))
				{
					// Change to owning.
					objsurElement.Attribute("t").Value = "o";

					// Change the guid.
					var guidAttr = objsurElement.Attribute("guid");
					var newCCRGuid = ccaGuidMap[new Guid(guidAttr.Value)];
					// Remember the owner guid (Chart) for the new CCR guid.
					// Key is the new guid for the new CCR.
					// Value is the owning chart.
					ccrOwnerGuidMap.Add(newCCRGuid, new Guid(chartDto.Guid));
					guidAttr.Value = newCCRGuid.ToString().ToLowerInvariant();
				}

				// Tell dto repos of the modification of the chart.
				chartDto.Xml = chartElement.ToString();
				dtoRepos.Update(chartDto);
			}

			// Migrate the CCR and CCA annotations.
			foreach (var oldCCR in oldCCRs)
			{
				// Collect up the inner class-level elements.
				var cmAnnotationBounds = new ElementBounds(oldCCR, s_tagsCmAnnotation);
				// May be null.
				var oldCompDetailsBounds = new ElementBounds(oldCCR, s_tagsCompDetails,
					cmAnnotationBounds.BeginTagOffset, cmAnnotationBounds.EndTagOffset);
				var oldTextBounds = new ElementBounds(oldCCR, s_tagsText,
					cmAnnotationBounds.BeginTagOffset, cmAnnotationBounds.EndTagOffset);
				// oldCommentBounds is unused. Hopefully by design?!
				//var oldCommentBounds = new ElementBounds(oldCCR, s_tagsComment,
				//    cmAnnotationBounds.BeginTagOffset, cmAnnotationBounds.EndTagOffset);
				// May be null, or at least have no 'objsur' elements.
				var refsFromAppliesTo = GetAppliesToObjsurGuids(oldCCR);

				// Try to make a Notes element. It may be null.
				XElement notesElement = null;
				if (oldTextBounds.IsValid)
				{
					// Get the StText dto and element.
					var stTextGuid = GetObjsurGuid(oldCCR, oldTextBounds.BeginTagOffset, oldTextBounds.EndTagOffset);
					if (!String.IsNullOrEmpty(stTextGuid))
					{
						var stTextDto = dtoRepos.GetDTO(stTextGuid);
						var stTextBounds = new ElementBounds(stTextDto.XmlBytes, s_tagsStText);
						var paragraphsBounds = new ElementBounds(stTextDto.XmlBytes, s_tagsParagraphs,
							stTextBounds.BeginTagOffset, stTextBounds.EndTagOffset);
						// See if stTextElement has any paras (StTxtPara)
						if (paragraphsBounds.IsValid)
						{
							// Get the first para.
							var firstParaGuid = GetObjsurGuid(stTextDto.XmlBytes,
								paragraphsBounds.BeginTagOffset, paragraphsBounds.EndTagOffset);
							if (!String.IsNullOrEmpty(firstParaGuid))
							{
								var firstParaDto = dtoRepos.GetDTO(firstParaGuid);
								var stTxtParaBounds = new ElementBounds(firstParaDto.XmlBytes,
									s_tagsStTxtPara);
								var contentsBounds = new ElementBounds(firstParaDto.XmlBytes,
									s_tagsContents,
									stTxtParaBounds.BeginTagOffset, stTxtParaBounds.EndTagOffset);
								var strBounds = new ElementBounds(firstParaDto.XmlBytes, s_tagsStr,
									contentsBounds.BeginTagOffset, contentsBounds.EndTagOffset);
								// See if it has any Contents.
								if (strBounds.IsValid)
								{
									// Move the Contents into a new Notes element.
									notesElement = new XElement("Notes",
										XElement.Parse(Encoding.UTF8.GetString(firstParaDto.XmlBytes,
											strBounds.BeginTagOffset, strBounds.Length)));
								}
							}
						}
					}
				}

				// Deal with 'ClauseType' property.
				var clauseTypeElement = new XElement("ClauseType",
					new XAttribute("val", "0"));
				// Deal with 'ClauseType' property.
				var endParagraphElement = new XElement("EndParagraph",
					new XAttribute("val", "False"));
				// Deal with 'ClauseType' property.
				var endSentenceElement = new XElement("EndSentence",
					new XAttribute("val", "False"));
				// Deal with 'ClauseType' property.
				var startDependentClauseGroupElement = new XElement("StartDependentClauseGroup",
					new XAttribute("val", "False"));
				// Deal with 'ClauseType' property.
				var endDependentClauseGroupElement = new XElement("EndDependentClauseGroup",
					new XAttribute("val", "False"));
				// See if some optional stuff in 'oldCompDetailsElement' will change it.
				var uniBounds = new ElementBounds(oldCCR, s_tagsUni,
					oldCompDetailsBounds.BeginTagOffset, oldCompDetailsBounds.EndTagOffset);
				if (uniBounds.IsValid)
				{
					// Turn its pseudo-xml string content into a real XElement.
					// It's string won't have angle brackets, so turn the entities into '<' and '>'
					// <CompDetails><Uni>&lt;ccinfo endSent="true"/&gt;</Uni></CompDetails>
					var ichMin = uniBounds.BeginTagOffset + s_tagsUni.BeginTag.Length;
					var ichLim = uniBounds.EndTagOffset;
					var cch = ichLim - ichMin;
					var details = Encoding.UTF8.GetString(oldCCR, ichMin, cch);
					if (details.Contains("&"))
						details = XmlUtils.DecodeXmlAttribute(details);
					var compDetailsElement = XElement.Parse(details);
					var optionalAttr = compDetailsElement.Attribute("dependent");
					var foundOverride = false;
					if (optionalAttr != null && optionalAttr.Value.ToLower() == "true")
					{
						clauseTypeElement.Attribute("val").Value = "1";
						foundOverride = true;
					}
					optionalAttr = compDetailsElement.Attribute("song");
					if (!foundOverride && optionalAttr != null && optionalAttr.Value.ToLower() == "true")
					{
						clauseTypeElement.Attribute("val").Value = "2";
						foundOverride = true;
					}
					optionalAttr = compDetailsElement.Attribute("speech");
					if (!foundOverride && optionalAttr != null && optionalAttr.Value.ToLower() == "true")
					{
						clauseTypeElement.Attribute("val").Value = "3";
					}
					// No more ClauseType attrs.
					// Move on to the other four optional boolean attrs.
					optionalAttr = compDetailsElement.Attribute("endSent");
					if (optionalAttr != null && optionalAttr.Value.ToLower() == "true")
						endSentenceElement.Attribute("val").Value = "True";

					optionalAttr = compDetailsElement.Attribute("endPara");
					if (optionalAttr != null && optionalAttr.Value.ToLower() == "true")
						endParagraphElement.Attribute("val").Value = "True";

					optionalAttr = compDetailsElement.Attribute("firstDep");
					if (optionalAttr != null && optionalAttr.Value.ToLower() == "true")
						startDependentClauseGroupElement.Attribute("val").Value = "True";

					optionalAttr = compDetailsElement.Attribute("endDep");
					if (optionalAttr != null && optionalAttr.Value.ToLower() == "true")
						endDependentClauseGroupElement.Attribute("val").Value = "True";
				}

				// Required 'Label' prop, which comes from the old 'Comment'
				// May be null, or at least have no 'objsur' elements.
				var enAltBounds = GetEnglishCommentBounds(oldCCR,
					cmAnnotationBounds.BeginTagOffset, cmAnnotationBounds.EndTagOffset);
				var enAlt = Encoding.UTF8.GetString(oldCCR, enAltBounds.BeginTagOffset, enAltBounds.Length);
				var enAltElement = XElement.Parse(enAlt);
				// Convert it to "Str" element with no "ws" attr.
				enAltElement.Name = "Str";
				enAltElement.Attribute("ws").Remove();

				// Create new ConstChartRow class (XElement & DTO).
				var oldGuid = GetGuid(oldCCR);
				var newGuid = ccaGuidMap[new Guid(oldGuid)];
				var owningGuid = ccrOwnerGuidMap[newGuid];
				ccrOwnerGuidMap.Remove(newGuid);
				const string className = "ConstChartRow";
				var newCCRElement = new XElement("rt",
					new XAttribute("class", className),
					new XAttribute("guid", newGuid),
					new XAttribute("ownerguid", owningGuid),
					new XElement("CmObject"),
					new XElement(className,
						notesElement, // May be null.
						clauseTypeElement,
						endParagraphElement,
						endSentenceElement,
						startDependentClauseGroupElement,
						endDependentClauseGroupElement,
						new XElement("Label", enAltElement),
						AddCells(dtoRepos,
							paraToOldSegments,
							halfBakedCcwgItems, refsFromAppliesTo, oldCCAs, ccaGuidMap, newGuid.ToString().ToLowerInvariant())));

				// Add DTO to repos.
				dtoRepos.Add(new DomainObjectDTO(newGuid.ToString().ToLowerInvariant(), className, newCCRElement.ToString()));
			}

			return halfBakedCcwgItems;
		}
Пример #14
0
		/// <summary>
		/// Changes the GUID of the specified DTO. It updates the owner and all specified referrers to point to the new GUID.
		/// </summary>
		/// <param name="dtoRepos">The dto repos.</param>
		/// <param name="dto">The dto.</param>
		/// <param name="newGuid">The new GUID.</param>
		/// <param name="possibleReferrers">The possible referrers.</param>
		internal static void ChangeGuid(IDomainObjectDTORepository dtoRepos, DomainObjectDTO dto, string newGuid,
			IEnumerable<DomainObjectDTO> possibleReferrers)
		{
			// if the DTO already has the new GUID, don't do anything
			if (dto.Guid.ToLowerInvariant() == newGuid.ToLowerInvariant())
				return;

			XElement rtElem = XElement.Parse(dto.Xml);
			rtElem.Attribute("guid").Value = newGuid;
			dtoRepos.Add(new DomainObjectDTO(newGuid, dto.Classname, rtElem.ToString()));
			foreach (DomainObjectDTO ownedDto in dtoRepos.GetDirectlyOwnedDTOs(dto.Guid))
			{
				XElement ownedElem = XElement.Parse(ownedDto.Xml);
				ownedElem.Attribute("ownerguid").Value = newGuid;
				UpdateDTO(dtoRepos, ownedDto, ownedElem.ToString());
			}

			var ownerDto = dtoRepos.GetOwningDTO(dto);
			if (ownerDto != null)
				UpdateObjSurElement(dtoRepos, ownerDto, dto.Guid, newGuid);

			if (possibleReferrers != null)
			{
				foreach (DomainObjectDTO referrer in possibleReferrers)
					UpdateObjSurElement(dtoRepos, referrer, dto.Guid, newGuid);
			}
			dtoRepos.Remove(dto);
		}
Пример #15
0
        public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
        {
            DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000040);

            // (WRONG) The ExcludeAsHeadword element only appears when @val="true" and
            // it is to be replaced by DoNotShowMainEntryIn with a list of all publications.
            // NB: The above statement is simply not true (RBR).
            // FW 7 writes out all primitive data properties.
            // The FW 6-FW7 migrator doesn't add them,
            // but FW 7 writes them the next time an object gets changed.

            // Make the list of publications once
            var newElt = new XElement("DoNotShowMainEntryIn");

            IEnumerable <XElement> dtoPubList = null;

            // XPATH: rt[Name/AUni='Publications']/Possibilities/objsur
            foreach (var a_list in domainObjectDtoRepository.AllInstancesSansSubclasses("CmPossibilityList"))
            {
                var xList = XElement.Parse(a_list.Xml);
                if (xList.XPathSelectElement("Name[AUni='Publications']") == null)
                {
                    continue;
                }
                dtoPubList = xList.XPathSelectElements("Possibilities/objsur");
                if (dtoPubList != null && dtoPubList.Count() > 0)
                {
                    break;
                }
            }

            if (dtoPubList == null || dtoPubList.Count() == 0) // add the Publications list to the project
            {                                                  // This list is owned by LexDb
                var ieDtoLexDb = domainObjectDtoRepository.AllInstancesSansSubclasses("LexDb");
                Debug.Assert(ieDtoLexDb != null && ieDtoLexDb.Count <DomainObjectDTO>() == 1, "Project has no LexDb Dto or more than one");
                var    dtoLexDb    = ieDtoLexDb.First <DomainObjectDTO>();
                var    xNode       = XElement.Parse(dtoLexDb.Xml);
                var    ksguidLexDb = xNode.Attribute("guid").Value;
                var    nowStr      = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                string xmlStrPub   =
                    "<rt guid=\"" + ksguidPubList + "\" class=\"CmPossibilityList\" ownerguid=\"" + ksguidLexDb + "\"><Name><AUni ws=\"en\">Publications</AUni></Name><DateCreated val=\"" + nowStr + "\" /><DateModified val=\"" + nowStr + "\" /><Depth val=\"1\" /><PreventChoiceAboveLevel val=\"0\" /><IsSorted val=\"True\" /><IsClosed val=\"False\" /><PreventDuplicates val=\"False\" /><PreventNodeChoices val=\"False\" /><UseExtendedFields val=\"False\" /><DisplayOption val=\"0\" /><ItemClsid val=\"7\" /><IsVernacular val=\"False\" /><WsSelector val=\"0\" /><ListVersion val=\"00000000-0000-0000-0000-000000000000\" /><Possibilities><objsur guid=\"" + ksguidMainDictionary + "\" t=\"o\" /></Possibilities></rt>";
                var dtoPub = new DomainObjectDTO(ksguidPubList, "CmPossibilityList", xmlStrPub);

                string xmlStrMD = "<rt guid=\"" + ksguidMainDictionary + "\" class=\"CmPossibility\" ownerguid=\"" + ksguidPubList + "\"><Name><AUni ws=\"en\">Main Dictionary</AUni></Name><Abbreviation><AUni ws=\"en\">Main</AUni></Abbreviation><SortSpec val=\"0\" /><DateCreated val=\"" + nowStr + "\" /><DateModified val=\"" + nowStr + "\" /><ForeColor val=\"0\" /><BackColor val=\"0\" /><UnderColor val=\"0\" /><UnderStyle val=\"0\" /><Hidden val=\"False\" /><IsProtected val=\"True\" /></rt>";
                var    dtoMD    = new DomainObjectDTO(ksguidMainDictionary, "CmPossibility", xmlStrMD);

                domainObjectDtoRepository.Add(dtoMD);
                domainObjectDtoRepository.Add(dtoPub);

                // Make xLexDb own dtoPub
                var xPts = xNode.Element("PublicationTypes");
                if (xPts == null)
                {                   // add one to LexDb
                    xPts = new XElement("PublicationTypes");
                    xPts.Add(DataMigrationServices.CreateOwningObjSurElement(ksguidPubList));
                    xNode.Add(xPts);
                }
                Debug.Assert(xPts != null, "LexDb has no PublicatonTypes and won't accept new ones.");
                dtoLexDb.Xml = xNode.ToString();
                domainObjectDtoRepository.Update(dtoLexDb);
                newElt.Add(DataMigrationServices.CreateReferenceObjSurElement(ksguidMainDictionary));
            }
            else
            {               // already had a publications list - add all to DoNotShowMainEntryIn
                foreach (var xElt in dtoPubList)
                {           // change the t attr to "r" reference instead of "o" own.
                    var xPubRef = new XElement(xElt);
                    xPubRef.SetAttributeValue("t", "r");
                    newElt.Add(xPubRef);
                }
            }
            foreach (var dto in domainObjectDtoRepository.AllInstancesSansSubclasses("LexEntry"))
            {
                // (WRONG) The ExcludeAsHeadword element only appears when @val="true" unless played with in a text editor
                // NB: The above statement is simply not true (RBR).
                // FW 7 writes out all primitive data properties.
                // The FW 6-FW7 migrator doesn't add them,
                // but FW 7 writes them the next time an object gets changed.
                var xElt       = XElement.Parse(dto.Xml);
                var exHeadword = xElt.Element("ExcludeAsHeadword");
                if (exHeadword == null)
                {
                    continue;
                }
                XAttribute XAval = exHeadword.Attribute("val");
                // It must be upper-case, since that is what is output.
                if (XAval.Value == "True")
                {                       // Add all publications from the list to this property
                    xElt.Add(new XElement(newElt));
                }
                exHeadword.Remove();                 // exHeadword.Value may be True, False or invalid
                dto.Xml = xElt.ToString();
                domainObjectDtoRepository.Update(dto);
            }
            DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
        }
Пример #16
0
		private static XElement AddNotes(IDomainObjectDTORepository dtoRepos, string newSegGuid, string oldSegGuid, Dictionary<string, List<byte[]>> notes)
		{
			// This method will create zero, or more, new Nt
			// instances, which will be owned by the new segment.
			// (Added to the new segment, when returned.)
			// Each new Nt object needs to be added to the repos,
			// and added as an owned object in the Notes prop of the new Segment.
			XElement retval = null;
			List<byte[]> oldNotes;
			if (notes.TryGetValue(oldSegGuid, out oldNotes))
			{
				retval = new XElement("Notes");
				foreach (var oldNotePair in oldNotes)
				{
					var newNoteGuid = Guid.NewGuid().ToString().ToLower();

					// Add to Notes element as owned objsur element.
					retval.Add(DataMigrationServices.CreateOwningObjSurElement(newNoteGuid));

					// Create the new Nt object.
					var newNoteElement = new XElement("rt",
						new XAttribute("class", "Note"),
						new XAttribute("guid", newNoteGuid),
						new XAttribute("ownerguid", newSegGuid.ToLower()),
						new XElement("CmObject"),
						new XElement("Note", GetOptionalComment(oldNotePair, "Content")));
					// Create new dto and add to repos.
					var newNoteDto = new DomainObjectDTO(newNoteGuid, "Note", newNoteElement.ToString());
					dtoRepos.Add(newNoteDto);
				}
			}
			return retval;
		}
Пример #17
0
		public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
		{
			DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000055);

			const string sPossibilityListGuid = "e491e5d5-d569-41f2-a9c1-23c048d55d59";
			const string className = "PhPhonData";
			var wmbList = domainObjectDtoRepository.AllInstancesSansSubclasses(className);
			var wmbPhonData = wmbList.FirstOrDefault();
			if (wmbPhonData == null)
			{ // somehow, this project does not have a PhPhonData object... add it
				const string sPhPhonDataGuid = "be765e3e-ea5e-11de-9d42-0013722f8dec";
				var wmbLangProjList = domainObjectDtoRepository.AllInstancesSansSubclasses("LangProj");
				var wmbLangProj = wmbLangProjList.First();
				var wmbLangProjElt = XElement.Parse(wmbLangProj.Xml);
				wmbLangProjElt.Add(new XElement("PhonologicalData",
								   new XElement("objsur",
												new XAttribute("guid", sPhPhonDataGuid),
												new XAttribute("t", "o"))));
				DataMigrationServices.UpdateDTO(domainObjectDtoRepository, wmbLangProj, wmbLangProjElt.ToString());
				// create new PhPhonData object
				var newPhPhonDataElt = new XElement("PhPhonData",
													new XAttribute("guid", sPhPhonDataGuid),
													new XAttribute("ownerguid", wmbLangProj.Guid));
				wmbPhonData = new DomainObjectDTO(sPhPhonDataGuid, "PhPhonData", newPhPhonDataElt.ToString());
				domainObjectDtoRepository.Add(wmbPhonData);
			}
			XElement wmbPhonDataElt = XElement.Parse(wmbPhonData.Xml);
			var wmbPhonDataGuid = wmbPhonDataElt.Attribute("guid").Value;

			// add phon rule feats contents
			wmbPhonDataElt.Add(new XElement("PhonRuleFeats",
											new XElement("objsur",
														 new XAttribute("guid", sPossibilityListGuid),
														 new XAttribute("t", "o"))));
			DataMigrationServices.UpdateDTO(domainObjectDtoRepository, wmbPhonData, wmbPhonDataElt.ToString());

			// create phon rule feats' possibility list
			var sb = new StringBuilder();
			sb.AppendFormat("<rt class=\"CmPossibilityList\" guid=\"{0}\" ownerguid=\"{1}\">", sPossibilityListGuid,
							wmbPhonDataGuid);
			sb.Append("<DateCreated val=\"2012-3-30 18:48:18.679\" />");
			sb.Append("<DateModified val=\"2012-3-30 18:48:18.679\" />");
			sb.Append("<Depth val=\"1\" />");
			sb.Append("<DisplayOption val=\"0\" />");
			sb.Append("<IsClosed val=\"False\" />");
			sb.Append("<IsSorted val=\"True\" />");
			sb.Append("<IsVernacular val=\"False\" />");
			sb.Append("<ItemClsid val=\"7\" />");
			sb.Append("<Name>");
			sb.Append("<AUni ws=\"en\">Phonological Rule Features</AUni>");
			sb.Append("</Name>");
			sb.Append("<Possibilities>");
			sb.Append("</Possibilities>");
			sb.Append("<PreventChoiceAboveLevel val=\"0\" />");
			sb.Append("<PreventDuplicates val=\"False\" />");
			sb.Append("<PreventNodeChoices val=\"False\" />");
			sb.Append("<UseExtendedFields val=\"False\" />");
			sb.Append("<WsSelector val=\"0\" />");
			sb.Append("</rt>");
			var newCmPossibilityListElt = XElement.Parse(sb.ToString());
			var dtoCmPossibilityList = new DomainObjectDTO(sPossibilityListGuid, "CmPossibilityList", newCmPossibilityListElt.ToString());
			domainObjectDtoRepository.Add(dtoCmPossibilityList);

			DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
		}
Пример #18
0
		/// <summary>
		/// Add a few items to the Notebook Record Type list, and rearrange the list a bit.  The original
		/// list should look something like:
		///		Conversation
		///		Interview
		///			Structured
		///			Unstructured
		///		Literature Summary
		///		Observation
		///			Performance
		///		Analysis
		///	After the migration, the list should look something like:
		///		Event
		///			Observation
		///			Conversation
		///			Interview
		///				Structured
		///				Unstructured
		///			Performance
		///		Literature Summary
		///		Analysis
		///		Methodology
		///		Weather
		/// </summary>
		/// <remarks>
		/// This implements FWR-643.  Note that users can edit this list, so any of the expected
		/// items could have been deleted or moved around in the list.  :-(
		/// </remarks>
		public void PerformMigration(IDomainObjectDTORepository repoDTO)
		{
			DataMigrationServices.CheckVersionNumber(repoDTO, 7000015);

			DomainObjectDTO dtoList = repoDTO.GetDTO(ksguidRecTypesList);
			XElement xeList = XElement.Parse(dtoList.Xml);
			XElement xeListPossibilities = xeList.XPathSelectElement("Possibilities");
			if (xeListPossibilities == null)
			{
				xeListPossibilities = new XElement("Possibilities");
				xeList.Add(xeListPossibilities);
			}
			// The user can edit the list, so these might possibly have been deleted (or moved).  :-(
			DomainObjectDTO dtoObservation = GetDTOIfItExists(repoDTO, ksguidObservation);
			DomainObjectDTO dtoConversation = GetDTOIfItExists(repoDTO, ksguidConversation);
			DomainObjectDTO dtoInterview = GetDTOIfItExists(repoDTO, ksguidInterview);
			DomainObjectDTO dtoPerformance = GetDTOIfItExists(repoDTO, ksguidPerformance);

			// Create the new Event, Methodology, and Weather record types.
			var nowStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

			StringBuilder sb = new StringBuilder();
			sb.AppendFormat("<rt class=\"CmPossibility\" guid=\"{0}\" ownerguid=\"{1}\">",
				ksguidEvent, ksguidRecTypesList);
			sb.Append("<Abbreviation><AUni ws=\"en\">Evnt</AUni></Abbreviation>");
			sb.Append("<Name><AUni ws=\"en\">Event</AUni></Name>");
			sb.AppendFormat("<DateCreated val=\"{0}\"/>", nowStr);
			sb.AppendFormat("<DateModified val=\"{0}\"/>", nowStr);
			sb.Append("</rt>");
			XElement xeEvent = XElement.Parse(sb.ToString());
			var dtoEvent = new DomainObjectDTO(ksguidEvent, "CmPossibility", xeEvent.ToString());
			repoDTO.Add(dtoEvent);
			xeListPossibilities.AddFirst(DataMigrationServices.CreateOwningObjSurElement(ksguidEvent));

			sb = new StringBuilder();
			sb.AppendFormat("<rt class=\"CmPossibility\" guid=\"{0}\" ownerguid=\"{1}\">",
				ksguidMethodology, ksguidRecTypesList);
			sb.Append("<Abbreviation><AUni ws=\"en\">Method</AUni></Abbreviation>");
			sb.Append("<Name><AUni ws=\"en\">Methodology</AUni></Name>");
			sb.AppendFormat("<DateCreated val=\"{0}\"/>", nowStr);
			sb.AppendFormat("<DateModified val=\"{0}\"/>", nowStr);
			sb.Append("</rt>");
			var dtoMethod = new DomainObjectDTO(ksguidMethodology, "CmPossibility", sb.ToString());
			repoDTO.Add(dtoMethod);
			xeListPossibilities.LastNode.AddAfterSelf(DataMigrationServices.CreateOwningObjSurElement(ksguidMethodology));

			sb = new StringBuilder();
			sb.AppendFormat("<rt class=\"CmPossibility\" guid=\"{0}\" ownerguid=\"{1}\">",
				ksguidWeather, ksguidRecTypesList);
			sb.Append("<Abbreviation><AUni ws=\"en\">Wthr</AUni></Abbreviation>");
			sb.Append("<Name><AUni ws=\"en\">Weather</AUni></Name>");
			sb.AppendFormat("<DateCreated val=\"{0}\"/>", nowStr);
			sb.AppendFormat("<DateModified val=\"{0}\"/>", nowStr);
			sb.Append("</rt>");
			var dtoWeather = new DomainObjectDTO(ksguidWeather, "CmPossibility", sb.ToString());
			repoDTO.Add(dtoWeather);
			xeListPossibilities.LastNode.AddAfterSelf(DataMigrationServices.CreateOwningObjSurElement(ksguidWeather));

			DataMigrationServices.UpdateDTO(repoDTO, dtoList, xeList.ToString());

			// Change the ownership links for the moved items.
			if (dtoObservation != null)
				ChangeOwner(repoDTO, dtoObservation, ksguidEvent, "SubPossibilities");
			if (dtoConversation != null)
				ChangeOwner(repoDTO, dtoConversation, ksguidEvent, "SubPossibilities");
			if (dtoInterview != null)
				ChangeOwner(repoDTO, dtoInterview, ksguidEvent, "SubPossibilities");
			if (dtoPerformance != null)
				ChangeOwner(repoDTO, dtoPerformance, ksguidEvent, "SubPossibilities");

			DataMigrationServices.IncrementVersionNumber(repoDTO);
		}
Пример #19
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);
		}
Пример #20
0
		private static XElement AddSegmentAnalyses(
			IDomainObjectDTORepository dtoRepos,
			IEnumerable<KeyValuePair<byte[], XElement>> halfBakedCcwgItemsForCurrentPara,
			byte[] oldSegElement,
			IDictionary<int, byte[]> xficsForCurrentPara,
			ICollection<byte[]> oldTextTags,
			string newSegmentGuid,
			bool isLastOldSegment,
			DomainObjectDTO paraDto)
		{
			XElement retval = null;

			var oldSegBeginOffset = GetBeginOffset(oldSegElement);
			var oldSegEndOffset = GetEndOffset(oldSegElement);

			var xficsForCurrentOldSegment = new SortedList<int, byte[]>();
			var halfBakedCcwgsForCurrentOldSegment = new List<XElement>();
			if (xficsForCurrentPara != null)
			{
				foreach (var kvp in xficsForCurrentPara)
				{
					var xficGuid = GetGuid(kvp.Value);
					var beginOffset = kvp.Key;

					// Try to find a CCWG that has a matching instanceOfGuid.
					XElement halfBakedCcwg = null;
					foreach (var halfBakedKvp in halfBakedCcwgItemsForCurrentPara)
					{
						// NB: halfBakedKvp.Value.Element("ConstChartWordGroup").Element("BeginAnalysisIndex").Attribute("val").Value.ToLower()
						// This is the 'InstanceOf' guid of the xfic, not the xfic's guid.
						if (
							halfBakedKvp.Value.Element("ConstChartWordGroup").Element("BeginAnalysisIndex").Attribute(
								"val").Value.ToLower() != xficGuid)
							continue;

						// If there happen to be more than one CCWG pointing to the same xfic, only one gets 'finished'!
						halfBakedCcwg = halfBakedKvp.Value;
						break;
					}

					if (beginOffset >= oldSegBeginOffset && beginOffset < oldSegEndOffset)
					{
						xficsForCurrentOldSegment.Add(beginOffset, kvp.Value);
						if (halfBakedCcwg != null)
							halfBakedCcwgsForCurrentOldSegment.Add(halfBakedCcwg);
					}
					else if (isLastOldSegment)
					{
						if (halfBakedCcwg != null)
							halfBakedCcwgsForCurrentOldSegment.Add(halfBakedCcwg);
						xficsForCurrentOldSegment.Add(beginOffset, kvp.Value);
					}
				}
			}

			if (xficsForCurrentOldSegment.Count > 0)
			{
				foreach (var key in xficsForCurrentOldSegment.Keys)
					xficsForCurrentPara.Remove(key);

				// The one returned element is "Analyses" (or null, if no twfics/pfics).
				// It will have one, or more, 'objsur' type 'r' elements in it.
				// The 'Analyses' property is a seq,
				// which is why is xficsForCurrentOldSegment is sorted the BeginOffset of the contained twfics/pfics.

				// All xfics will have an 'InstanceOf' by now, even pfics.
				// The pfics had a new InstanceOf prop set earlier
				// (or were removed, if InstanceOf could not be set),
				// and twfics with no InstanceOf prop were filtered out earlier.
				retval = new XElement("Analyses",
					from xfix in xficsForCurrentOldSegment.Values
					select DataMigrationServices.CreateReferenceObjSurElement(GetInstanceOfGuid(xfix)));

				// Finish converting half-baked CCWG stuff.
				if (halfBakedCcwgsForCurrentOldSegment.Count > 0)
				{
					var allOldXficGuids = (from xfix in xficsForCurrentOldSegment.Values
										   select GetGuid(xfix).ToLower()).ToList();
					foreach (var halfBakedCcwg in halfBakedCcwgsForCurrentOldSegment)
					{
						// Fix up halfbaked CCWG items here.
						var innerElement = halfBakedCcwg.Element("ConstChartWordGroup");
						// NB: The guids temporarily stored in the begin/end index props are for
						// the xfic guid, but we want to look up the index of its InstanceOf property,
						// which will be what is actually in the new "Analyses" prop of the new Segment.
						var guidAttr = innerElement.Element("BeginAnalysisIndex").Attribute("val");
						guidAttr.Value = allOldXficGuids.IndexOf(guidAttr.Value.ToLower()).ToString();
						guidAttr = innerElement.Element("EndAnalysisIndex").Attribute("val");
						guidAttr.Value = allOldXficGuids.IndexOf(guidAttr.Value.ToLower()).ToString();
						// NB: The recently created CCWG has already been added to dto repos,
						// so the only remaining task is to update the xml on the CCWG dto.
						var dto = dtoRepos.GetDTO(GetGuid(halfBakedCcwg));
						dto.Xml = halfBakedCcwg.ToString();
					}
				}

				// Find and convert any any old Text Tag indirect annotations for this segment.
				// NB: xficsForCurrentOldSegment.Values may have pfics,
				// and we don't want those here.
				// oldTextTags is all old TextTag annotations for everything.
				// This variable holds the twfics (in BeginOffset order),
				// where pfics are removed from xficsForCurrentOldSegment.
				var twficBeginOffsetListForCurrentSegment = new List<int>();
				var twficGuidListForCurrentSegment = new List<string>();
				var twficElementListForCurrentSegment = new List<byte[]>();
				var twficMap = new Dictionary<string, byte[]>();
				foreach (var twficKvp in from xficKvp in xficsForCurrentOldSegment
										 where GetAnnotationTypeGuid(xficKvp.Value) == DataMigrationServices.kTwficAnnDefnGuid
										 select xficKvp)
				{
					twficBeginOffsetListForCurrentSegment.Add(twficKvp.Key);
					var twficGuid = GetGuid(twficKvp.Value);
					twficGuidListForCurrentSegment.Add(twficGuid);
					twficElementListForCurrentSegment.Add(twficKvp.Value);
					twficMap.Add(twficGuid, twficKvp.Value);
				}

				var textTagElementsForCurrentSegment = new List<byte[]>();
				foreach (var oldTextTagAnnElement in oldTextTags)
				{
					// Find the ones that are used in the current segment,
					// and add them to textTagElementsForCurrentSegment.

					var appliesToGuids = new List<string>();
					foreach (var guid in GetAppliesToObjsurGuids(oldTextTagAnnElement))
					{
						if (twficGuidListForCurrentSegment.Contains(guid))
							appliesToGuids.Add(guid);
					}
					if (appliesToGuids.Count() <= 0)
						continue;

					// Store them for a while.
					textTagElementsForCurrentSegment.Add(oldTextTagAnnElement);

					// Get the index of the First twfic in appliesToGuids collection (which may hold pfics)
					// and the index of the Last twfic in appliesToGuids collection (which may hold pfics).
					var beginIdx = 0;
					for (var i = 0; i < appliesToGuids.Count(); ++i)
					{
						var currentXfixGuid = appliesToGuids[i].ToLower();
						byte[] currentTwficElement;
						if (!twficMap.TryGetValue(currentXfixGuid, out currentTwficElement))
							continue;

						beginIdx = xficsForCurrentOldSegment.IndexOfValue(currentTwficElement);
						break;
					}
					var endIdx = 0;
					for (var i = appliesToGuids.Count() - 1; i > -1; --i)
					{
						var currentXfixGuid = appliesToGuids[i].ToLower();
						byte[] currentTwficElement;
						if (!twficMap.TryGetValue(currentXfixGuid, out currentTwficElement))
							continue;

						endIdx = xficsForCurrentOldSegment.IndexOfValue(currentTwficElement);
						break;
					}

					var owningStText = dtoRepos.GetOwningDTO(paraDto);
					var newTextTagGuid = Guid.NewGuid().ToString().ToLower();
					var newTextTagElement = new XElement("rt",
						new XAttribute("class", "TextTag"),
						new XAttribute("guid", newTextTagGuid),
						new XAttribute("ownerguid", owningStText.Guid.ToLower()),
						new XElement("CmObject"),
						new XElement("TextTag",
							new XElement("BeginSegment", DataMigrationServices.CreateReferenceObjSurElement(newSegmentGuid)),
							new XElement("EndSegment", DataMigrationServices.CreateReferenceObjSurElement(newSegmentGuid)),
							new XElement("BeginAnalysisIndex", new XAttribute("val", beginIdx)),
							new XElement("EndAnalysisIndex", new XAttribute("val", endIdx)),
							new XElement("Tag", DataMigrationServices.CreateReferenceObjSurElement(GetInstanceOfGuid(oldTextTagAnnElement)))));

					// Add new DTO to repos.
					var newTextTagDto = new DomainObjectDTO(newTextTagGuid, "TextTag", newTextTagElement.ToString());
					dtoRepos.Add(newTextTagDto);
					// Add new TextTag to owning prop on owner as objsur element.
					var owningStTextElement = XElement.Parse(owningStText.Xml);
					var innerStTextElement = owningStTextElement.Element("StText");
					var tagsPropElement = innerStTextElement.Element("Tags");
					if (tagsPropElement == null)
					{
						tagsPropElement = new XElement("Tags");
						innerStTextElement.Add(tagsPropElement);
					}
					tagsPropElement.Add(DataMigrationServices.CreateOwningObjSurElement(newTextTagGuid));
					// Tell repos of the modification.
					owningStText.Xml = owningStTextElement.ToString();
					dtoRepos.Update(owningStText);
				}
				// Remove current text tags from input list
				foreach (var currentTextTagElement in textTagElementsForCurrentSegment)
					oldTextTags.Remove(currentTextTagElement);
			}
			//else
			//{
			//    // No xfics at all, so make sure para is set to be tokenized again.
			//    // Done globally for each Para in ProcessParagraphs
			//    //MarkParaAsNeedingTokenization(dtoRepos, paraDto, paraElement);
			//}

			return retval;
		}
Пример #21
0
        /// <summary>
        /// Creates a CmPossibilityList with all the basic properties filled in for the xml (necessary for S/R) and adds it to the dto
        /// </summary>
        /// <param name="dtoRepo">the created list will be added to this IDomainObjectDTORepository</param>
        /// <param name="listGuid">guid to use for this list</param>
        /// <param name="ownerGuid">guid of the object that owns this list</param>
        /// <param name="languageAbbrAndNames">Tuple of language id, abbreviation, and name for the list</param>
        /// <param name="createTime">DateTime to use as the DateCreated and DateModified for this list</param>
        /// <param name="wsSelector">e.g. WritingSystemServices.kwsVernAnals</param>
        /// <param name="possibilityItems">array of guids for possibilityItems to add if any</param>
        /// <param name="itemType">the class id of items which this list can contain, defaults to 7 (CmPossibility)</param>
        public static void CreatePossibilityList(IDomainObjectDTORepository dtoRepo, string listGuid, string ownerGuid,
                                                 Tuple <string, string, string>[] languageAbbrAndNames, DateTime createTime, int wsSelector, string[] possibilityItems = null, int itemType = 7)
        {
            var existingList = FindMatchingCustomList(dtoRepo.AllInstancesWithSubclasses("CmPossibilityList"),
                                                      languageAbbrAndNames);

            if (existingList != null)
            {
                var listElement = XElement.Parse(existingList.Xml);
                var names       = listElement.Elements("Name");
                foreach (var titleElement in names.Select(name => name.Element("AUni")).Where(titleElement => titleElement != null))
                {
                    titleElement.Value = titleElement.Value + "-Custom";
                }
                UpdateDTO(dtoRepo, existingList, listElement.ToString());
            }
            var sb = new StringBuilder();

            sb.AppendFormat("<rt class=\"CmPossibilityList\" guid=\"{0}\" ownerguid=\"{1}\">", listGuid,
                            ownerGuid);
            sb.Append("<Abbreviation>");
            foreach (var abbr in languageAbbrAndNames)
            {
                sb.Append(string.Format("<AUni ws=\"{0}\">{1}</AUni>", abbr.Item1, abbr.Item2));
            }
            sb.Append("</Abbreviation>");
            sb.AppendFormat("<DateCreated val=\"{0:yyyy-MM-dd HH:mm:ss.fff}\" />", createTime);
            sb.AppendFormat("<DateModified val=\"{0:yyyy-MM-dd HH:mm:ss.fff}\" />", createTime);
            sb.Append("<Depth val=\"1\" />");
            sb.Append("<DisplayOption val=\"0\" />");
            sb.Append("<IsClosed val=\"False\" />");
            sb.Append("<IsSorted val=\"True\" />");
            sb.Append("<IsVernacular val=\"False\" />");
            sb.Append("<ListVersion val=\"00000000-0000-0000-0000-000000000000\" />");
            sb.AppendFormat("<ItemClsid val=\"{0}\" />", itemType);
            sb.Append("<Name>");
            foreach (var abbr in languageAbbrAndNames)
            {
                sb.Append(string.Format("<AUni ws=\"{0}\">{1}</AUni>", abbr.Item1, abbr.Item3));
            }
            sb.Append("</Name>");
            if (possibilityItems != null)
            {
                sb.Append("<Possibilities>");
                foreach (var possibilityGuid in possibilityItems)
                {
                    sb.Append(string.Format("<objsur guid=\"{0}\" t=\"o\" />", possibilityGuid));
                }
                sb.Append("</Possibilities>");
            }
            sb.Append("<PreventChoiceAboveLevel val=\"0\" />");
            sb.Append("<PreventDuplicates val=\"True\" />");
            sb.Append("<PreventNodeChoices val=\"True\" />");
            sb.Append("<UseExtendedFields val=\"False\" />");
            sb.Append(string.Format("<WsSelector val=\"{0}\" />", wsSelector));
            sb.Append("</rt>");

            var newList = new DomainObjectDTO(listGuid, "CmPossibilityList", sb.ToString());

            dtoRepo.Add(newList);
        }
Пример #22
0
		private void ChangeInvalidGuid(IDomainObjectDTORepository repoDto, LexTypeInfo info,
			string name, string guidStd)
		{
			var xaGuid = info.XmlElement.Attribute("guid");
			if (xaGuid == null)
				throw new Exception("The object does not have a guid -- this is impossible!");
			xaGuid.SetValue(guidStd);
			var guidBad = info.DTO.Guid;
			if (!m_mapBadGoodGuids.ContainsKey(guidBad))
				m_mapBadGoodGuids.Add(guidBad, guidStd);
			var className = info.DTO.Classname;
			repoDto.Remove(info.DTO);
			info.DTO = new DomainObjectDTO(guidStd, className, info.XmlElement.ToString());
			repoDto.Add(info.DTO);
			// Fix the owning reference (but only if it's one of the two lists, because otherwise
			// it might be contained in a LexTypeInfo that hasn't yet been processed).
			var bad = String.Format("guid=\"{0}\"", guidBad);
			var good = String.Format("guid=\"{0}\"", guidStd);
			var bad2 = String.Format("guid='{0}'", guidBad);	// probably pure paranoia...
			var good2 = String.Format("guid='{0}'", guidStd);
			DomainObjectDTO dtoOwner;
			if (repoDto.TryGetOwner(info.DTO.Guid, out dtoOwner) && dtoOwner.Classname == "CmPossibilityList")
			{
				dtoOwner.Xml = dtoOwner.Xml.Replace(bad, good).Replace(bad2, good2);
				repoDto.Update(dtoOwner);
			}
			// Fix any references from LexEntryRef objects.
			foreach (var dtoRef in repoDto.AllInstancesWithSubclasses("LexEntryRef"))
			{
				var xml = dtoRef.Xml;
				if (xml.Contains(guidBad))
				{
					dtoRef.Xml = xml.Replace(bad, good).Replace(bad2, good2);
					repoDto.Update(dtoRef);
				}
			}
			m_mapNameGuid.Remove(name);
			m_mapGuidName.Remove(guidStd);
		}
Пример #23
0
		private static DomainObjectDTO MakeEvaluation(string ownerGuid, IDomainObjectDTORepository domainObjectDtoRepository, XElement agentElement, string owningAttr)
		{
			var newGuid = Guid.NewGuid().ToString().ToLower();
			var newEvalElt = new XElement("rt",
				new XAttribute("class", "CmAgentEvaluation"),
				new XAttribute("guid", newGuid),
				new XAttribute("ownerguid", ownerGuid),
				new XElement("CmObject"),
				new XElement("CmAgentEvaluation"));
			// Create new dto and add to repos.
			var newEval = new DomainObjectDTO(newGuid, "CmAgentEvaluation", newEvalElt.ToString());
			domainObjectDtoRepository.Add(newEval);
			agentElement.Add(new XElement(owningAttr,
				new XElement("objsur", new XAttribute("t", "o"), new XAttribute("guid", newGuid))));

			return newEval;
		}
Пример #24
0
		private static bool EnsurePficHasInstanceOf(
			IDomainObjectDTORepository dtoRepos,
			DomainObjectDTO dtoPfic,
			IDictionary<string, DomainObjectDTO> newPunctForms)
		{
			var pficElement = dtoPfic.XmlBytes;
			/*
<Contents>
	<Str>
		<Run ws="eZPI">Ne Wlalo lo San Juan. </Run>
		<Run ws="es">Otras cosas.</Run>
	</Str>
</Contents>
			*/
			// Find relevant paragraph from BeginObject property of 'pficElement'.
			var paraDto = dtoRepos.GetDTO(GetBeginObjectGuid(pficElement));
			var beginOffset = GetBeginOffset(pficElement);
			var endOffset = GetEndOffset(pficElement);

			if (beginOffset > endOffset)
			{
				// Bad begin or end offset.
				MarkParaAsNeedingTokenization(dtoRepos, paraDto);
				return false;
			}
			if (beginOffset < 0)
			{
				// Bad begin offset.
				MarkParaAsNeedingTokenization(dtoRepos, paraDto);
				return false;
			}
			// Concatenate data from all runs.
			List<string> writingSystems;
			var runs = GetParagraphContentRuns(paraDto.XmlBytes, out writingSystems);
			Debug.Assert(runs.Count == writingSystems.Count);
			var bldr = new StringBuilder();
			for (int i = 0; i < runs.Count; ++i)
				bldr.Append(runs[i]);
			var fullParaContents = Icu.Normalize(bldr.ToString(), Icu.UNormalizationMode.UNORM_NFD);
			if (endOffset > fullParaContents.Length)
			{
				// Total string is too short (end offset beyond end of string).
				MarkParaAsNeedingTokenization(dtoRepos, paraDto);
				return false;
			}
			// Find the form of the punctuation mark.
			var newForm = fullParaContents.Substring(beginOffset, endOffset - beginOffset);
			if (newForm == String.Empty)
			{
				// No punctuation form at all.
				MarkParaAsNeedingTokenization(dtoRepos, paraDto);
				return false;
			}
			var icuLocale = String.Empty;
			// Find the ws's IcuLocale at the begin offset in whichever run it is in.
			var currentTotalLength = 0;
			for (var i = 0; i < runs.Count; ++i)
			{
				var currentRunText = Icu.Normalize(runs[i], Icu.UNormalizationMode.UNORM_NFD);
				currentTotalLength += currentRunText.Length;
				if (beginOffset >= currentTotalLength)
					continue; // Not in this run.

				if (endOffset > currentTotalLength)
				{
					// It starts in one run and ends in another, so bail out.
					MarkParaAsNeedingTokenization(dtoRepos, paraDto);
					return false;
				}
				// It's all in this run, so quit looking at runs.
				icuLocale = writingSystems[i];
				break;
			}

			if (icuLocale == String.Empty)
			{
				// Hard to say how we can get here, but something is very wrong.
				MarkParaAsNeedingTokenization(dtoRepos, paraDto);
				return false;
			}

			// If the new PF is all in one run, and we have its IcuLocale,
			// then make the new PF object, and return true.
			// Find/Create PunctuationForm object that has a Form in the matching IcuLocale & matching string.
			var key = icuLocale + "-" + newForm;
			DomainObjectDTO dtoMatchingPf;
			if (!newPunctForms.TryGetValue(key, out dtoMatchingPf))
			{
				// Create new PunctuationForm dto.
				var newPunctFormGuid = Guid.NewGuid().ToString().ToLower();
				const string className = "PunctuationForm";
				var newPfElement = new XElement("rt",
					new XAttribute("class", className),
					new XAttribute("guid", newPunctFormGuid),
					new XElement("CmObject"),
					new XElement("PunctuationForm",
						new XElement("Form",
							new XElement("Str",
								new XElement("Run", new XAttribute("ws", icuLocale), newForm)))));
				dtoMatchingPf = new DomainObjectDTO(newPunctFormGuid, className, newPfElement.ToString());
				// Add new PunctuationForm to dtoRepos.
				dtoRepos.Add(dtoMatchingPf);
				// Add new PunctuationForm to newPunctForms.
				newPunctForms.Add(key, dtoMatchingPf);
			}

			// Assign InstanceOf for pficElement to matching PunctuationForm object.
			// NB: No need to mess with registering it as modified,
			// since it gets deleted anyway later on.
			var innerBounds = new ElementBounds(pficElement, s_tagsCmAnnotation);
			Debug.Assert(innerBounds.IsValid);
			var pficBytes = new List<byte>(pficElement);
			var instanceOf = String.Format("<InstanceOf>{1}{0}{1}</InstanceOf>{1}",
				DataMigrationServices.CreateReferenceObjSurElement(dtoMatchingPf.Guid), Environment.NewLine);
			pficBytes.InsertRange(innerBounds.EndTagOffset, Encoding.UTF8.GetBytes(instanceOf));
			dtoPfic.XmlBytes = pficBytes.ToArray();
			return true;
		}
Пример #25
0
		// Make a new CmFile element for the specified path, and an objsur child of langCmFolder to own it.
		// In this migration a typical result would be:
		//    <rt guid="c4f4760e-049e-49af-ac57-73c686100700" class="CmFile" ownerguid="3e615e09-3b86-4fae-adfe-5fc2473214b6">
		//    <InternalPath>
		//        <Uni>C:\FwWW\DistFiles\AudioVisual\NotInLinkedFilesPath.WMV</Uni>
		//    </InternalPath>
		//    </rt>
		private void MakeCmFile(IDomainObjectDTORepository domainObjectDtoRepository, string langCmFolderGuid,
			XElement langCmFolder, string path)
		{
			string cmFileGuid;
			cmFileGuid = Guid.NewGuid().ToString();
			var cmFileXElement = new XElement("rt",
										 new XAttribute("guid", cmFileGuid),
										 new XAttribute("class", "CmFile"),
										 new XAttribute("ownerguid", langCmFolderGuid),
										 MakeUnicode("InternalPath", path));
			var dtoConfirmed = new DomainObjectDTO(cmFileGuid, "CmFile", cmFileXElement.ToString());
			domainObjectDtoRepository.Add(dtoConfirmed);
			langCmFolder.Element("Files").Add(MakeOwningSurrogate(cmFileGuid));
		}
Пример #26
0
		private static IEnumerable<XElement> ConvertCCAsAndAddCCRObjSurElements(
			IDomainObjectDTORepository dtoRepos,
			IDictionary<string, SortedList<int, byte[]>> paraToOldSegments,
			ICollection<KeyValuePair<byte[], XElement>> halfBakedCcwgItems,
			IDictionary<string, byte[]> oldCCAs,
			IDictionary<Guid, Guid> ccaGuidMap,
			List<string> objsurElementGuids,
			string owningCCRGuid)
		{
			// 'retval' will be put into the new CCR of the caller as owning objsur elements.
			var retval = new List<XElement>(objsurElementGuids.Count());

			// Decide which class to convert the old CCA to:
			//	1. CmBaseAnnotations -> ConstChartTag
			//	2. CmIndirectAnnotation
			//		A. 1 (or more) CCRs in AppliesTo-> ConstChartClauseMarker
			//		B. 1 (only) CCA in AppliesTo -> ConstChartMovedTextMarker
			//		C. null AppliesTo -> ConstChartWordGroup
			//		D. 1 (or more) twfics (pfics?) -> ConstChartWordGroup
			const string kChangeMe = "CHANGEME";
			foreach (var oldCCAGuid in objsurElementGuids)
			{
				var guidOldCCA = new Guid(oldCCAGuid);
				// Earlier 'SortOutMultipleXficBackRefs()' may have left a dangling reference.
				// If so, skip it.
				//XElement oldAnnElement;
				byte[] oldAnnElement;
				if (!oldCCAs.TryGetValue(oldCCAGuid, out oldAnnElement))
					continue;
				//var oldAnnElement = oldCCAs[oldCCAGuid];
				// Leave it in, so we can get at its XElement, whenever needed.
				//oldCCAs.Remove(oldCCAGuid);
				var guidNew = ccaGuidMap[guidOldCCA];
				var newGuid = guidNew.ToString().ToLowerInvariant();
				var newClassName = kChangeMe;
				// Collect up the inner class-level elements.
				var cmAnnotationBounds = new ElementBounds(oldAnnElement, s_tagsCmAnnotation);
				if (!cmAnnotationBounds.IsValid)
					continue;
				// Fix FWR-2139 crash migrating because of missing InstanceOf
				// Skip chart annotation with no column reference.
				var guidInstanceOf = GetInstanceOfGuid(oldAnnElement);
				if (String.IsNullOrEmpty(guidInstanceOf))
					continue;
				var mergesAfterElement = new XElement("MergesAfter", new XAttribute("val", "False"));
				var mergesBeforeElement = new XElement("MergesBefore", new XAttribute("val", "False"));
				// May be null.
				var compDetailsBounds = new ElementBounds(oldAnnElement, s_tagsCompDetails,
					cmAnnotationBounds.BeginTagOffset, cmAnnotationBounds.EndTagOffset);
				if (compDetailsBounds.IsValid)
				{
					var uniBounds = new ElementBounds(oldAnnElement, s_tagsUni,
						compDetailsBounds.BeginTagOffset, compDetailsBounds.EndTagOffset);
					if (uniBounds.IsValid)
					{
						// See if some optional stuff in 'oldCompDetailsElement' will change MergesAfter or MergesBefore.
						var mergeAfter = GetAttributeValue(oldAnnElement, s_mergeAfterAttr,
							uniBounds.BeginTagOffset, uniBounds.EndTagOffset);
						if (mergeAfter == "true")
							mergesAfterElement.Attribute("val").Value = "True";
						var mergeBefore = GetAttributeValue(oldAnnElement, s_mergeBeforeAttr,
							uniBounds.BeginTagOffset, uniBounds.EndTagOffset);
						if (mergeBefore == "true")
							mergesBeforeElement.Attribute("val").Value = "True";
					}
				}
				// Reset the Name and add other elements really soon now,
				// depending on which subclass of ConstituentChartCellPart is used.
				var newSpecificClassElement = new XElement(newClassName);
				var newClassAttr = new XAttribute("class", newClassName);
				var newCCAElement = new XElement("rt",
					newClassAttr,
					new XAttribute("guid", newGuid),
					new XAttribute("ownerguid", owningCCRGuid),
					new XElement("CmObject"),
					new XElement("ConstituentChartCellPart",
						new XElement("Column",
							new XElement("objsur",
								new XAttribute("t", "r"),
								new XAttribute("guid", guidInstanceOf))),
						mergesAfterElement,
						mergesBeforeElement),
					newSpecificClassElement);

				var classValue = GetClassValue(oldAnnElement);
				switch (classValue)
				{
					default:
						throw new InvalidOperationException("Unrecognized annotation class used as CCA.");
					case "CmBaseAnnotation":
						// #1.
						newClassName = "ConstChartTag";
						newSpecificClassElement.Name = newClassName;
						newClassAttr.Value = newClassName;
						// Tag is atomic ref.
						var guidBeginObject = GetBeginObjectGuid(oldAnnElement);
						if (!String.IsNullOrEmpty(guidBeginObject))
						{
							newSpecificClassElement.Add(
								new XElement("Tag",
									new XElement("objsur",
										new XAttribute("t", "r"),
										new XAttribute("guid", guidBeginObject))));
						}
						break;
					case "CmIndirectAnnotation":
						// #2.
						// Get the optional 'AppliesTo' element.
						var refsFromAppliesTo = GetAppliesToObjsurGuids(oldAnnElement);
						if (refsFromAppliesTo == null || refsFromAppliesTo.Count == 0)
						{
							// 2.C
							newClassName = "ConstChartWordGroup";
							newSpecificClassElement.Name = newClassName;
							newClassAttr.Value = newClassName;
							// BeginSegment & EndSegment are to be null, so leave them out altogether.
							// BeginAnalysisIndex & EndAnalysisIndex are both -1.
							// Note: This is actually wrong; this should be a ConstChartTag with no Tag
							//    But it gets fixed in DM7000013.
							newSpecificClassElement.Add(new XElement("BeginAnalysisIndex", new XAttribute("val", "-1")));
							newSpecificClassElement.Add(new XElement("EndAnalysisIndex", new XAttribute("val", "-1")));
						}
						else
						{
							// Get the class of the first (or only) objsur.
							var currentRefGuid = refsFromAppliesTo[0];
							var currentInnerTarget = oldCCAs[refsFromAppliesTo[0]];
							switch (GetAnnotationTypeGuid(currentInnerTarget))
							{
								default:
									throw new InvalidOperationException("Unrecognized annotation type for CCA.");
								case DataMigrationServices.kConstituentChartRowAnnDefnGuid:
									// One, or more, CCRs.
									// 2.A
									newClassName = "ConstChartClauseMarker";
									newSpecificClassElement.Name = newClassName;
									newClassAttr.Value = newClassName;
									var dependentClausesElement = new XElement("DependentClauses");
									newSpecificClassElement.Add(dependentClausesElement);
									foreach (var guid in refsFromAppliesTo)
									{
										// DependentClauses is ref. seq. prop.
										dependentClausesElement.Add(
											DataMigrationServices.CreateReferenceObjSurElement(
												ccaGuidMap[new Guid(guid)].ToString().ToLowerInvariant()));
									}
									break;
								case DataMigrationServices.kConstituentChartAnnotationAnnDefnGuid:
									// Single CCA.
									// 2.B
									newClassName = "ConstChartMovedTextMarker";
									newSpecificClassElement.Name = newClassName;
									newClassAttr.Value = newClassName;
									// WordGroup - Get new guid from cca guid map using old CCA guid.
									newSpecificClassElement.Add(new XElement("WordGroup",
										DataMigrationServices.CreateReferenceObjSurElement(ccaGuidMap[new Guid(currentRefGuid)].ToString().ToLowerInvariant())));
									// Preposed - Boolean.
									// The data migration for the Preposed boolean is simple.
									// If the old Marker's Comment property contains a string "<<" then it's true,
									// false otherwise.
									newSpecificClassElement.Add(new XElement("Preposed",
										new XAttribute("val",
											GetPreposedBooleanFromComment(oldAnnElement,
												cmAnnotationBounds.BeginTagOffset, cmAnnotationBounds.EndTagOffset))));
									break;
								case DataMigrationServices.kPficAnnDefnGuid: // Fall through.
								case DataMigrationServices.kTwficAnnDefnGuid:
									// One, or more, twfics/pfics
									// These all go into halfBakedCcwgItems,
									// and will be finished when Segments and xfics are finished.

									// NB: While there may be multiple xfics,
									// only the first and last are stored in the two indices.
									var firstXficGuid = currentRefGuid;
									var lastXficGuid = refsFromAppliesTo[refsFromAppliesTo.Count - 1];
									var firstXficInnerAnnElement = XElement.Parse(dtoRepos.GetDTO(firstXficGuid).Xml).Element("CmBaseAnnotation");
									// Gotta make sure the xfics and segments are in the same paragraph.
									var paraGuid = GetGuid(firstXficInnerAnnElement.Element("BeginObject").Element("objsur"));
									var beginOffsetElement = firstXficInnerAnnElement.Element("BeginOffset");
									var firstXfixBeginOffset = beginOffsetElement == null ? 0 : int.Parse(beginOffsetElement.Attribute("val").Value);
									var newSegmentGuid = kChangeMe;

									try
									{
										foreach (var kvp in paraToOldSegments[paraGuid].TakeWhile(kvp => kvp.Key <= firstXfixBeginOffset))
										{
											// Found the right segment, so get its new segment guid.
											newSegmentGuid = ccaGuidMap[new Guid(GetGuid(kvp.Value))].ToString().ToLowerInvariant();
										}
									}
									catch (KeyNotFoundException)
									{
										// Upon finding an orphaned chart cell with an invalid paragraph, skip it.
										continue;
									}
									if (newSegmentGuid == kChangeMe)
									{
										// We might have some segments (better check), but there are xfics that aren't
										// covered by a segment, so try to recover the broken data, as much as possible.
										newSegmentGuid = AddExtraInitialSegment(paraGuid, ccaGuidMap, paraToOldSegments);
									}

									halfBakedCcwgItems.Add(new KeyValuePair<byte[], XElement>(oldAnnElement, newCCAElement));
									newClassName = "ConstChartWordGroup";
									newSpecificClassElement.Name = newClassName;
									newClassAttr.Value = newClassName;
									newSpecificClassElement.Add(new XElement("BeginSegment",
										DataMigrationServices.CreateReferenceObjSurElement(newSegmentGuid)));
									newSpecificClassElement.Add(new XElement("EndSegment",
										DataMigrationServices.CreateReferenceObjSurElement(newSegmentGuid)));
									// For now, just store the guid of the first xfic.
									// It's the wrong data type, but xml won't care,
									// and, they will get changed later on.
									newSpecificClassElement.Add(new XElement("BeginAnalysisIndex",
										new XAttribute("val", firstXficGuid)));
									// For now, just store the guid of the last xfic.
									// It's the wrong data type, but xml won't care,
									// and, they will get changed later on.
									newSpecificClassElement.Add(new XElement("EndAnalysisIndex",
										new XAttribute("val", lastXficGuid)));
									break;
							}
						}
						break;
				}

				// Create new owning objSur Element.
				retval.Add(DataMigrationServices.CreateOwningObjSurElement(newGuid));

				// Add newly converted CCA to repos.
				dtoRepos.Add(new DomainObjectDTO(newGuid, newClassName, newCCAElement.ToString()));
			}

			return retval;
		}
Пример #27
0
        /// <summary>
        /// Add a few items to the Notebook Record Type list, and rearrange the list a bit.  The original
        /// list should look something like:
        ///		Conversation
        ///		Interview
        ///			Structured
        ///			Unstructured
        ///		Literature Summary
        ///		Observation
        ///			Performance
        ///		Analysis
        ///	After the migration, the list should look something like:
        ///		Event
        ///			Observation
        ///			Conversation
        ///			Interview
        ///				Structured
        ///				Unstructured
        ///			Performance
        ///		Literature Summary
        ///		Analysis
        ///		Methodology
        ///		Weather
        /// </summary>
        /// <remarks>
        /// This implements FWR-643.  Note that users can edit this list, so any of the expected
        /// items could have been deleted or moved around in the list.  :-(
        /// </remarks>
        public void PerformMigration(IDomainObjectDTORepository repoDTO)
        {
            DataMigrationServices.CheckVersionNumber(repoDTO, 7000015);

            DomainObjectDTO dtoList             = repoDTO.GetDTO(ksguidRecTypesList);
            XElement        xeList              = XElement.Parse(dtoList.Xml);
            XElement        xeListPossibilities = xeList.XPathSelectElement("Possibilities");

            if (xeListPossibilities == null)
            {
                xeListPossibilities = new XElement("Possibilities");
                xeList.Add(xeListPossibilities);
            }
            // The user can edit the list, so these might possibly have been deleted (or moved).  :-(
            DomainObjectDTO dtoObservation  = GetDTOIfItExists(repoDTO, ksguidObservation);
            DomainObjectDTO dtoConversation = GetDTOIfItExists(repoDTO, ksguidConversation);
            DomainObjectDTO dtoInterview    = GetDTOIfItExists(repoDTO, ksguidInterview);
            DomainObjectDTO dtoPerformance  = GetDTOIfItExists(repoDTO, ksguidPerformance);

            // Create the new Event, Methodology, and Weather record types.
            var nowStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("<rt class=\"CmPossibility\" guid=\"{0}\" ownerguid=\"{1}\">",
                            ksguidEvent, ksguidRecTypesList);
            sb.Append("<Abbreviation><AUni ws=\"en\">Evnt</AUni></Abbreviation>");
            sb.Append("<Name><AUni ws=\"en\">Event</AUni></Name>");
            sb.AppendFormat("<DateCreated val=\"{0}\"/>", nowStr);
            sb.AppendFormat("<DateModified val=\"{0}\"/>", nowStr);
            sb.Append("</rt>");
            XElement xeEvent  = XElement.Parse(sb.ToString());
            var      dtoEvent = new DomainObjectDTO(ksguidEvent, "CmPossibility", xeEvent.ToString());

            repoDTO.Add(dtoEvent);
            xeListPossibilities.AddFirst(DataMigrationServices.CreateOwningObjSurElement(ksguidEvent));

            sb = new StringBuilder();
            sb.AppendFormat("<rt class=\"CmPossibility\" guid=\"{0}\" ownerguid=\"{1}\">",
                            ksguidMethodology, ksguidRecTypesList);
            sb.Append("<Abbreviation><AUni ws=\"en\">Method</AUni></Abbreviation>");
            sb.Append("<Name><AUni ws=\"en\">Methodology</AUni></Name>");
            sb.AppendFormat("<DateCreated val=\"{0}\"/>", nowStr);
            sb.AppendFormat("<DateModified val=\"{0}\"/>", nowStr);
            sb.Append("</rt>");
            var dtoMethod = new DomainObjectDTO(ksguidMethodology, "CmPossibility", sb.ToString());

            repoDTO.Add(dtoMethod);
            xeListPossibilities.LastNode.AddAfterSelf(DataMigrationServices.CreateOwningObjSurElement(ksguidMethodology));

            sb = new StringBuilder();
            sb.AppendFormat("<rt class=\"CmPossibility\" guid=\"{0}\" ownerguid=\"{1}\">",
                            ksguidWeather, ksguidRecTypesList);
            sb.Append("<Abbreviation><AUni ws=\"en\">Wthr</AUni></Abbreviation>");
            sb.Append("<Name><AUni ws=\"en\">Weather</AUni></Name>");
            sb.AppendFormat("<DateCreated val=\"{0}\"/>", nowStr);
            sb.AppendFormat("<DateModified val=\"{0}\"/>", nowStr);
            sb.Append("</rt>");
            var dtoWeather = new DomainObjectDTO(ksguidWeather, "CmPossibility", sb.ToString());

            repoDTO.Add(dtoWeather);
            xeListPossibilities.LastNode.AddAfterSelf(DataMigrationServices.CreateOwningObjSurElement(ksguidWeather));

            DataMigrationServices.UpdateDTO(repoDTO, dtoList, xeList.ToString());

            // Change the ownership links for the moved items.
            if (dtoObservation != null)
            {
                ChangeOwner(repoDTO, dtoObservation, ksguidEvent, "SubPossibilities");
            }
            if (dtoConversation != null)
            {
                ChangeOwner(repoDTO, dtoConversation, ksguidEvent, "SubPossibilities");
            }
            if (dtoInterview != null)
            {
                ChangeOwner(repoDTO, dtoInterview, ksguidEvent, "SubPossibilities");
            }
            if (dtoPerformance != null)
            {
                ChangeOwner(repoDTO, dtoPerformance, ksguidEvent, "SubPossibilities");
            }

            DataMigrationServices.IncrementVersionNumber(repoDTO);
        }
Пример #28
0
		// Creates a CmFolder whose owning guid is the langProjectGuid passed as a child of the element passed
		// and gives it the name passed. In this migration a typical result (after later code adds the Files) would be:
		// <rt guid="3e615e09-3b86-4fae-adfe-5fc2473214b6" class="CmFolder" ownerguid="b8bdad3d-9006-46f0-83e8-ae1d1726f2ad">
		//    <Name>
		//        <AUni ws="pt">File paths in TsStrings</AUni>
		//    </Name>
		//    <Files>
		//        <objsur guid="c4f3760e-049e-49af-ac57-73c686100700" t="o" />
		//        <objsur guid="c4f4760e-049e-49af-ac57-73c686100700" t="o" />
		//    </Files>
		//</rt>
		private XElement MakeCmFolder(IDomainObjectDTORepository domainObjectDtoRepository, string langProjectGuid,
			XElement filePathsInTsStringsCmFolder, string name, out DomainObjectDTO folderDto)
		{
			string cmFolderGuid;
			cmFolderGuid = Guid.NewGuid().ToString();
			var cmFolderXML = new XElement("rt",
										 new XAttribute("guid", cmFolderGuid),
										 new XAttribute("class", "CmFolder"),
										 new XAttribute("ownerguid", langProjectGuid),
										 MakeMultiUnicode("Name", name),
										 new XElement("Files"));
			folderDto = new DomainObjectDTO(cmFolderGuid, "CmFolder", cmFolderXML.ToString());
			domainObjectDtoRepository.Add(folderDto);
			filePathsInTsStringsCmFolder.Add(MakeOwningSurrogate(cmFolderGuid));
			return cmFolderXML;
		}
Пример #29
0
        public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository)
        {
            DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000055);

            const string sPossibilityListGuid = "e491e5d5-d569-41f2-a9c1-23c048d55d59";
            const string className            = "PhPhonData";
            var          wmbList     = domainObjectDtoRepository.AllInstancesSansSubclasses(className);
            var          wmbPhonData = wmbList.FirstOrDefault();

            if (wmbPhonData == null)
            {             // somehow, this project does not have a PhPhonData object... add it
                const string sPhPhonDataGuid = "be765e3e-ea5e-11de-9d42-0013722f8dec";
                var          wmbLangProjList = domainObjectDtoRepository.AllInstancesSansSubclasses("LangProj");
                var          wmbLangProj     = wmbLangProjList.First();
                var          wmbLangProjElt  = XElement.Parse(wmbLangProj.Xml);
                wmbLangProjElt.Add(new XElement("PhonologicalData",
                                                new XElement("objsur",
                                                             new XAttribute("guid", sPhPhonDataGuid),
                                                             new XAttribute("t", "o"))));
                DataMigrationServices.UpdateDTO(domainObjectDtoRepository, wmbLangProj, wmbLangProjElt.ToString());
                // create new PhPhonData object
                var newPhPhonDataElt = new XElement("PhPhonData",
                                                    new XAttribute("guid", sPhPhonDataGuid),
                                                    new XAttribute("ownerguid", wmbLangProj.Guid));
                wmbPhonData = new DomainObjectDTO(sPhPhonDataGuid, "PhPhonData", newPhPhonDataElt.ToString());
                domainObjectDtoRepository.Add(wmbPhonData);
            }
            XElement wmbPhonDataElt  = XElement.Parse(wmbPhonData.Xml);
            var      wmbPhonDataGuid = wmbPhonDataElt.Attribute("guid").Value;

            // add phon rule feats contents
            wmbPhonDataElt.Add(new XElement("PhonRuleFeats",
                                            new XElement("objsur",
                                                         new XAttribute("guid", sPossibilityListGuid),
                                                         new XAttribute("t", "o"))));
            DataMigrationServices.UpdateDTO(domainObjectDtoRepository, wmbPhonData, wmbPhonDataElt.ToString());

            // create phon rule feats' possibility list
            var sb = new StringBuilder();

            sb.AppendFormat("<rt class=\"CmPossibilityList\" guid=\"{0}\" ownerguid=\"{1}\">", sPossibilityListGuid,
                            wmbPhonDataGuid);
            sb.Append("<DateCreated val=\"2012-3-30 18:48:18.679\" />");
            sb.Append("<DateModified val=\"2012-3-30 18:48:18.679\" />");
            sb.Append("<Depth val=\"1\" />");
            sb.Append("<DisplayOption val=\"0\" />");
            sb.Append("<IsClosed val=\"False\" />");
            sb.Append("<IsSorted val=\"True\" />");
            sb.Append("<IsVernacular val=\"False\" />");
            sb.Append("<ItemClsid val=\"7\" />");
            sb.Append("<Name>");
            sb.Append("<AUni ws=\"en\">Phonological Rule Features</AUni>");
            sb.Append("</Name>");
            sb.Append("<Possibilities>");
            sb.Append("</Possibilities>");
            sb.Append("<PreventChoiceAboveLevel val=\"0\" />");
            sb.Append("<PreventDuplicates val=\"False\" />");
            sb.Append("<PreventNodeChoices val=\"False\" />");
            sb.Append("<UseExtendedFields val=\"False\" />");
            sb.Append("<WsSelector val=\"0\" />");
            sb.Append("</rt>");
            var newCmPossibilityListElt = XElement.Parse(sb.ToString());
            var dtoCmPossibilityList    = new DomainObjectDTO(sPossibilityListGuid, "CmPossibilityList", newCmPossibilityListElt.ToString());

            domainObjectDtoRepository.Add(dtoCmPossibilityList);

            DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository);
        }
Пример #30
0
		private static void ProcessParagraphs(
			IDomainObjectDTORepository dtoRepos,
			IDictionary<string, byte[]> oldCCAs,
			IEnumerable<KeyValuePair<byte[], XElement>> halfBakedCcwgItems,
			IDictionary<string, SortedList<int, byte[]>> paraToOldSegments,
			IDictionary<string, SortedList<int, byte[]>> paraToOldXfics,
			IDictionary<Guid, Guid> ccaGuidMap,
			ICollection<byte[]> oldTextTags,
			Dictionary<string, List<byte[]>> freeTrans,
			Dictionary<string, List<byte[]>> litTrans,
			Dictionary<string, List<byte[]>> notes)
		{
			var dtos = dtoRepos.AllInstancesWithSubclasses("StTxtPara");
			//var count = dtos.Count();
			//var num = 0;
			//var cpara = 0;
			foreach (var currentParaDto in dtos)
			{
				//++num;
				// If it has no contents, then skip it.
				var stTxtParaBounds = new ElementBounds(currentParaDto.XmlBytes, s_tagsStTxtPara);
				if (!stTxtParaBounds.IsValid)
					continue;
				var contentsBounds = new ElementBounds(currentParaDto.XmlBytes, s_tagsContents,
					stTxtParaBounds.BeginTagOffset, stTxtParaBounds.EndTagOffset);
				if (!contentsBounds.IsValid)
					continue;
				//++cpara;

				// Mark the paragraph as needing retokenization.
				MarkParaAsNeedingTokenization(dtoRepos, currentParaDto);

				var currentParaGuid = currentParaDto.Guid.ToLower();
				SortedList<int, byte[]> xficsForCurrentPara;
				paraToOldXfics.TryGetValue(currentParaGuid, out xficsForCurrentPara);

				SortedList<int, byte[]> segsForCurrentPara;
				if (!paraToOldSegments.TryGetValue(currentParaGuid, out segsForCurrentPara)
					&& xficsForCurrentPara != null
					&& xficsForCurrentPara.Count > 0)
				{
					// We have no segments at all, but there are xfics, so try to recover the broken data,
					// as much as possible.
					// Need to create a new old segment XElement (not dto), to try and and keep old data.
					var guidBrandNewSeg = Guid.NewGuid();
					var brandNewSegGuid = guidBrandNewSeg.ToString().ToLower();
					ccaGuidMap.Add(guidBrandNewSeg, guidBrandNewSeg);
					segsForCurrentPara = new SortedList<int, byte[]>();
					paraToOldSegments.Add(currentParaGuid, segsForCurrentPara);
					var bldr = new StringBuilder();
					bldr.AppendFormat("<rt guid=\"{0}\"", brandNewSegGuid);
					bldr.Append("<CmObject/>");
					bldr.Append("<CmBaseAnnotation>");
					bldr.Append("<BeginOffset val=\"0\"/>");
					bldr.AppendFormat("<EndOffset val=\"{0}\"/>", int.MaxValue);
					bldr.Append("</CmBaseAnnotation>");
					bldr.Append("</rt>");
					segsForCurrentPara.Add(0, Encoding.UTF8.GetBytes(bldr.ToString()));
				}

				// If the para has no segs or xfics, skip the following work.
				if (segsForCurrentPara == null)
					continue;

				if (xficsForCurrentPara != null && xficsForCurrentPara.Count > 0 && segsForCurrentPara.Count > 0)
				{
					// We have both segments and xfics. Check for odd case (like FWR-3081)
					// where the first segment starts AFTER the first xfic, and add a new
					// segment that covers the text up to the first current segment.
					if (xficsForCurrentPara.First().Key < segsForCurrentPara.First().Key)
						AddExtraInitialSegment(currentParaGuid, ccaGuidMap, paraToOldSegments);
				}
				var halfBakedCcwgItemsForCurrentPara = new List<KeyValuePair<byte[], XElement>>();
				List<string> writingSystems;
				var runs = GetParagraphContentRuns(currentParaDto.XmlBytes, out writingSystems);
				// We may well have segments with no xfics, for example, Scripture that has segmented BT.
				if (xficsForCurrentPara != null)
				{

					// Since pfics/wfics were 'optional' and usually not maintained in the db,
					// we need to make sure there is a dummy one in xficsForCurrentPara
					// in order to get the correct Begin/EndAnalysisIndex for chart and tagging objects
					// It turns out we don't need to worry about ws and exact begin/end character offsets.
					// All we need to end up with correct indices is the correct NUMBER of xfics.
					var context = new ParagraphContext(currentParaGuid, xficsForCurrentPara);
					EnsureAllXfics(runs, context);

					// Find any 'halfbaked' items for the current paragraph.
					// Get the para for the first objsur's guid (some twfic ann),
					// in the CmIndirectAnnotation's AppliesTo prop.
					foreach (var kvp in halfBakedCcwgItems)
					{
						var refs = GetAppliesToObjsurGuids(kvp.Key);
						if (refs == null || refs.Count == 0)
							continue;
						var guid = refs[0];
						var dto = dtoRepos.GetDTO(guid);
						var guidBegin = GetBeginObjectGuid(dto.XmlBytes);
						if (guidBegin == currentParaGuid)
							halfBakedCcwgItemsForCurrentPara.Add(kvp);
					}
				}
				var bldrSegmentsElement = new StringBuilder();
				var numberOfOldSegmentsInCurrentPara = segsForCurrentPara.Values.Count;
				var currentOldSegmentIdx = 1;
				foreach (var currentOldSegInCurrentPara in segsForCurrentPara.Values)
				{
					var isLastOldSegment = (currentOldSegmentIdx++ == numberOfOldSegmentsInCurrentPara);
					var oldSegGuid = GetGuid(currentOldSegInCurrentPara);
					var guidOldSeg = new Guid(oldSegGuid);
					var newSegGuid = ccaGuidMap[guidOldSeg].ToString().ToLowerInvariant();
					// Add it to Segments prop of currentParaElement,
					var objsur = DataMigrationServices.CreateOwningObjSurElement(newSegGuid);
					bldrSegmentsElement.AppendLine(objsur.ToString());

					// Create new XElement for new segment.
					var newSegmentElement =
						new XElement("rt",
							new XAttribute("class", "Segment"),
							new XAttribute("guid", newSegGuid),
							new XAttribute("ownerguid", currentParaDto.Guid.ToLower()),
							new XElement("CmObject"),
							new XElement("Segment",
								AddBeginOffset(GetBeginOffset(currentOldSegInCurrentPara)),
								AddFreeTranslation(oldSegGuid, freeTrans),
								AddLiteralTranslation(oldSegGuid, litTrans),
								AddNotes(dtoRepos, newSegGuid, oldSegGuid, notes),
								AddSegmentAnalyses(dtoRepos,
									halfBakedCcwgItemsForCurrentPara,
									currentOldSegInCurrentPara,
									xficsForCurrentPara,
									oldTextTags,
									newSegGuid,
									isLastOldSegment,
									currentParaDto)));
					newSegmentElement = DeleteTemporaryAnalyses(newSegmentElement);
					// Create a new Segment instance DTO from the 'newSegmentElement',
					// and add it to repos.
					var newSegDto = new DomainObjectDTO(newSegGuid, "Segment", newSegmentElement.ToString());
					dtoRepos.Add(newSegDto);
				}

				paraToOldSegments.Remove(currentParaGuid.ToLower());
				paraToOldXfics.Remove(currentParaGuid.ToLower());

				if (bldrSegmentsElement.Length == 0)
					continue;
				bldrSegmentsElement.Insert(0, "<Segments>");
				bldrSegmentsElement.Append("</Segments>");

				// Add paraSegmentsElement to current para.
				var segBytes = Encoding.UTF8.GetBytes(bldrSegmentsElement.ToString());
				var xmlNew = new List<byte>(currentParaDto.XmlBytes.Length + segBytes.Length);
				xmlNew.AddRange(currentParaDto.XmlBytes);
				stTxtParaBounds = new ElementBounds(currentParaDto.XmlBytes, s_tagsStTxtPara);
				xmlNew.InsertRange(stTxtParaBounds.EndTagOffset, segBytes);
				// Tell DTO repos about the modification.
				DataMigrationServices.UpdateDTO(dtoRepos, currentParaDto, xmlNew.ToArray());
			}
		}