private static void WriteOptionalCustomProperties(XmlWriter writer, string pathRoot) { // Write out optional custom property data to the fwdata file. // The foo.CustomProperties file will exist, even if it has nothing in it, but the "AdditionalFields" root element. var optionalCustomPropFile = Path.Combine(pathRoot, SharedConstants.CustomPropertiesFilename); var doc = XDocument.Load(optionalCustomPropFile); var customFieldElements = doc.Root.Elements(SharedConstants.CustomField).ToList(); if (!customFieldElements.Any()) { return; } var mdc = MetadataCache.MdCache; foreach (var cf in customFieldElements) { // Remove 'key' attribute from CustomField elements, before writing to main file. cf.Attribute("key").Remove(); // Restore type attr for object values. var propType = cf.Attribute("type").Value; cf.Attribute("type").Value = MetadataCache.RestoreAdjustedTypeValue(propType); mdc.GetClassInfo(cf.Attribute(SharedConstants.Class).Value).AddProperty( new FdoPropertyInfo(cf.Attribute(SharedConstants.Name).Value, propType, true)); } mdc.ResetCaches(); FileWriterService.WriteElement(writer, doc.Root); }
internal static void PushHumptyOffTheWall(IProgress progress, bool writeVerbose, string mainFilePathname) { Guard.AgainstNull(progress, "progress"); FileWriterService.CheckFilename(mainFilePathname); var rootDirectoryName = Path.GetDirectoryName(mainFilePathname); // NB: This is strictly an ordered list of method calls. // Don't even 'think' of changing any of them. CheckForUserCancelRequested(progress); DeleteOldFiles(rootDirectoryName); CheckForUserCancelRequested(progress); WriteVersionFile(mainFilePathname); // Outer Dict has the class name for its key and a sorted (by guid) dictionary as its value. // The inner dictionary has a caseless guid as the key and the byte array as the value. // (Only has current concrete classes.) var classData = GenerateBasicClassData(); var wellUsedElements = new Dictionary <string, XElement> { { SharedConstants.LangProject, null }, { SharedConstants.LexDb, null } }; var guidToClassMapping = WriteOrCacheProperties(mainFilePathname, classData, wellUsedElements); CheckForUserCancelRequested(progress); BaseDomainServices.PushHumptyOffTheWall(progress, writeVerbose, rootDirectoryName, wellUsedElements, classData, guidToClassMapping); #if DEBUG // Enable ONLY for testing a round trip. // FLExProjectUnifier.PutHumptyTogetherAgain(progress, writeVerbose, mainFilePathname); #endif }
internal static void WriteVersionFile(string mainFilePathname) { var pathRoot = Path.GetDirectoryName(mainFilePathname); var version = FieldWorksProjectServices.GetVersionNumber(mainFilePathname); FileWriterService.WriteVersionNumberFile(pathRoot, version); MetadataCache.MdCache.UpgradeToVersion(Int32.Parse(version)); }
private static Dictionary <string, string> WriteOrCacheProperties(string mainFilePathname, Dictionary <string, SortedDictionary <string, byte[]> > classData, Dictionary <string, XElement> wellUsedElements) { var pathRoot = Path.GetDirectoryName(mainFilePathname); var mdc = MetadataCache.MdCache; // Key is the guid of the object, and value is the class name. var guidToClassMapping = new Dictionary <string, string>(); using (var fastSplitter = new FastXmlElementSplitter(mainFilePathname)) { var haveWrittenCustomFile = false; bool foundOptionalFirstElement; // NB: The main input file *does* have to deal with the optional first element. foreach (var record in fastSplitter.GetSecondLevelElementBytes(SharedConstants.AdditionalFieldsTag, SharedConstants.RtTag, out foundOptionalFirstElement)) { if (foundOptionalFirstElement) { // 2. Write custom properties file with custom properties. FileWriterService.WriteCustomPropertyFile(mdc, pathRoot, record); foundOptionalFirstElement = false; haveWrittenCustomFile = true; } else { CacheDataRecord(record, wellUsedElements, classData, guidToClassMapping); } } if (!haveWrittenCustomFile) { // Write empty custom properties file. FileWriterService.WriteCustomPropertyFile(Path.Combine(pathRoot, SharedConstants.CustomPropertiesFilename), null); } } return(guidToClassMapping); }
internal static void PutHumptyTogetherAgain(IProgress progress, bool writeVerbose, string mainFilePathname) { Guard.AgainstNull(progress, "progress"); FileWriterService.CheckPathname(mainFilePathname); using (var tempFile = new TempFile()) { using (var writer = XmlWriter.Create(tempFile.Path, new XmlWriterSettings // NB: These are the FW bundle of settings, not the canonical settings. { OmitXmlDeclaration = false, CheckCharacters = true, ConformanceLevel = ConformanceLevel.Document, Encoding = new UTF8Encoding(false), Indent = true, IndentChars = (""), NewLineOnAttributes = false })) { var pathRoot = Path.GetDirectoryName(mainFilePathname); // NB: The method calls are strictly ordered. // Don't even think of changing them. if (writeVerbose) { progress.WriteVerbose("Processing data model version number...."); } else { progress.WriteMessage("Processing data model version number...."); } UpgradeToVersion(writer, pathRoot); if (writeVerbose) { progress.WriteVerbose("Processing custom properties...."); } else { progress.WriteMessage("Processing custom properties...."); } WriteOptionalCustomProperties(writer, pathRoot); var sortedData = BaseDomainServices.PutHumptyTogetherAgain(progress, writeVerbose, pathRoot); if (writeVerbose) { progress.WriteVerbose("Writing temporary fwdata file...."); } else { progress.WriteMessage("Writing temporary fwdata file...."); } foreach (var rtElement in sortedData.Values) { FileWriterService.WriteElement(writer, rtElement); } writer.WriteEndElement(); } //Thread.Sleep(2000); In case it blows (access denied) up again on Sue's computer. if (writeVerbose) { progress.WriteVerbose("Copying temporary fwdata file to main file...."); } else { progress.WriteMessage("Copying temporary fwdata file to main file...."); } File.Copy(tempFile.Path, mainFilePathname, true); } SplitFileAgainIfNeeded(progress, writeVerbose, mainFilePathname); }