Exemple #1
0
        public void GenerateMlCustomString()
        {
            IFwMetaDataCache mdc         = FwMetaDataCacheClass.Create();
            string           m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory,
                                                        @"DbAccess\Test\SampleCm.xml");

            mdc.InitXml(m_sTestPath, true);

            XmlDocument docSrc = new XmlDocument();

            docSrc.LoadXml(
                "<generate class=\"LexEntry\" fieldType=\"mlstring\" restrictions=\"customOnly\"> "
                + "<column label=\"$label\"> "
                + "<seq field=\"Senses\" sep=\"$delimiter:commaSpace\"> "
                + "<string field=\"$fieldName\" ws=\"$ws:analysis\" class=\"LexEntry\"/> "
                + "</seq> "
                + "</column> "
                + "</generate>");
            XmlNode source = TestXmlViewsUtils.GetRootNode(docSrc, "generate");

            Assert.IsNotNull(source);

            PartGenerator generator = new PartGenerator(mdc, source);

            string[] fields = generator.FieldNames;
            Assert.AreEqual(1, fields.Length);
            Assert.IsTrue(StringArrayIncludes(fields, "custom"));

            XmlNode[] results = generator.Generate();

            // SampleCm.xml has three ML attrs on LexEntry
            Assert.AreEqual(1, results.Length);

            XmlDocument docExpected3 = new XmlDocument();

            docExpected3.LoadXml(
                "<column label=\"Restrictions\" originalLabel=\"Restrictions\" > "
                + "<seq field=\"Senses\" sep=\"$delimiter:commaSpace\"> "
                + "<string field=\"custom\" ws=\"$ws:analysis\" class=\"LexEntry\"/> "
                + "</seq> "
                + "</column>");
            XmlNode expected3 = TestXmlViewsUtils.GetRootNode(docExpected3, "column");

            Assert.IsTrue(SomeNodeMatches(results, expected3));
        }
Exemple #2
0
        public void GenerateParts()
        {
            IFwMetaDataCache mdc         = FwMetaDataCacheClass.Create();
            string           m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory,
                                                        @"DbAccess\Test\SampleCm.xml");

            mdc.InitXml(m_sTestPath, true);

            XmlDocument docSrc = new XmlDocument();

            docSrc.LoadXml(
                "<root> "
                + "<dummy1/> "
                + "<generate class=\"LexEntry\" fieldType=\"mlstring\" restrictions=\"none\"> "
                + "<column label=\"$fieldName\"> "
                + "<seq field=\"Senses\" sep=\"$delimiter:commaSpace\"> "
                + "<string field=\"$fieldName\" ws=\"$ws:analysis\"/> "
                + "</seq> "
                + "</column> "
                + "</generate> "
                + "<dummy2/> "
                + "<generate class=\"LexEntry\" fieldType=\"mlstring\" restrictions=\"none\"> "
                + "<dummyG label=\"$fieldName\"/> "
                + "</generate> "
                + "<dummy3/> "
                + "<dummy4/> "
                + "</root>");
            XmlNode source = TestXmlViewsUtils.GetRootNode(docSrc, "root");

            Assert.IsNotNull(source);

            List <XmlNode> nodes = PartGenerator.GetGeneratedChildren(source, mdc);

            Assert.AreEqual(1 + 3 + 1 + 3 + 2, nodes.Count);
            Assert.AreEqual("dummy1", nodes[0].Name);
            Assert.AreEqual("dummy2", nodes[4].Name);
            Assert.AreEqual("dummy3", nodes[8].Name);
            Assert.AreEqual("dummy4", nodes[9].Name);
            Assert.IsTrue(NameAndLabelOccur(nodes, 1, 4, "column", "CitationForm"));
            Assert.IsTrue(NameAndLabelOccur(nodes, 1, 4, "column", "Bibliography"));
            Assert.IsTrue(NameAndLabelOccur(nodes, 5, 8, "dummyG", "CitationForm"));
            Assert.IsTrue(NameAndLabelOccur(nodes, 5, 8, "dummyG", "custom"));
        }
Exemple #3
0
		/// <summary>
		/// Create a RealDataCache object, and laod it with metadata and real data.
		/// </summary>
		/// <param name="metadataPathname"></param>
		/// <param name="realDataPathname"></param>
		/// <param name="objects"></param>
		/// <returns></returns>
		public RealDataCache LoadCache(string metadataPathname, string realDataPathname, Dictionary<int, uint> objects)
		{
			CheckDisposed();

			m_realDataCache = new RealDataCache();
			m_realDataCache.CheckWithMDC = false;

			try
			{
#if DEBUG
				//Process objectBrowser = Process.GetCurrentProcess();
				//long memory = objectBrowser.PrivateMemorySize64;
				//Debug.WriteLine(String.Format("Memory used (start load): {0}.", memory.ToString()));

				DateTime start = DateTime.Now;
#endif
				m_metaDataCache = new MetaDataCache();
				m_metaDataCache.InitXml(metadataPathname, true);
				m_realDataCache.MetaDataCache = m_metaDataCache;
#if DEBUG
				DateTime end = DateTime.Now;
				TimeSpan span = new TimeSpan(end.Ticks - start.Ticks);
				string totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
					span.Hours.ToString(), span.Minutes.ToString(), span.Seconds.ToString(), span.Milliseconds.ToString());
				Debug.WriteLine("Time to load MDC: " + totalTime);
				start = end;
				//memory = objectBrowser.PrivateMemorySize64;
				//Debug.WriteLine(String.Format("Memory used (loaded MDC load): {0}.", memory.ToString()));
#endif

				XmlDocument doc = new XmlDocument();
				doc.Load(realDataPathname);
#if DEBUG
				end = DateTime.Now;
				span = new TimeSpan(end.Ticks - start.Ticks);
				totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
					span.Hours.ToString(), span.Minutes.ToString(), span.Seconds.ToString(), span.Milliseconds.ToString());
				Debug.WriteLine("Time to load XML: " + totalTime);
				start = end;
				//memory = objectBrowser.PrivateMemorySize64;
				//Debug.WriteLine(String.Format("Memory used (loaded data XML): {0}.", memory.ToString()));
#endif

				// Load Writing Systems first.
				int ord = 0;
				int hvo;
				uint clid = 0;
				{
					XmlNodeList wsNodes = doc.DocumentElement.SelectNodes("LgWritingSystem");
					uint flid = m_metaDataCache.GetFieldId("LgWritingSystem", "ICULocale", false);
					// We need a full list of ints and strings for Wses,
					// before we can load string data,
					// so cache the barebones first.
					foreach (XmlNode wsNode in wsNodes)
					{
						hvo = BootstrapWs(wsNode, flid, out clid, objects);
					}
					foreach (XmlNode wsNode in wsNodes)
					{
						string uid = wsNode.Attributes["id"].Value.Substring(1);
						hvo = m_realDataCache.get_ObjFromGuid(new Guid(uid));
						LoadObject(wsNode, hvo, clid, objects);
					}
				}
				// Now load other ownerless objects, except LangProject and Wses.
				foreach (XmlNode otherOwnerlessNode in doc.DocumentElement.ChildNodes)
				{
					if (otherOwnerlessNode.Name != "LangProject" && otherOwnerlessNode.Name != "LgWritingSystem")
					{
						hvo = LoadCmObjectProperties(otherOwnerlessNode, 0, 0, ord, out clid, objects);
						LoadObject(otherOwnerlessNode, hvo, clid, objects);
					}
				}
				// Now load LangProject
				XmlNode langProjectNode = doc.DocumentElement.SelectSingleNode("LangProject");
				hvo = LoadCmObjectProperties(langProjectNode, 0, 0, ord, out clid, objects);
				LoadObject(langProjectNode, hvo, clid, objects);

				// Set references
				// Set atomic references
				foreach (KeyValuePair<HvoFlidKey, XmlNode> kvp in m_delayedAtomicReferences)
				{
					string uid = kvp.Value.Attributes["target"].Value.Substring(1);
					try
					{
						int hvoTarget = m_realDataCache.get_ObjFromGuid(new Guid(uid));
						m_realDataCache.CacheObjProp(kvp.Key.Hvo, (int)kvp.Key.Flid, hvoTarget);
					}
					catch
					{
						// Invalid reference. Just clear the cache in case there is a save.
						m_realDataCache.SetObjProp(kvp.Key.Hvo, (int)kvp.Key.Flid, 0);
					}
				}
				//// Remove all items from m_delayedAtomicReferences that are in handledRefs.
				//// Theory has it that m_delayedAtomicReferences should then be empty.
				m_delayedAtomicReferences.Clear();

				// Set vector (col or seq) references.
				foreach (KeyValuePair<HvoFlidKey, List<XmlNode>> kvp in m_delayedVecterReferences)
				{
					List<int> hvos = new List<int>();
					foreach (XmlNode obj in kvp.Value)
					{
						string uid = obj.Attributes["target"].Value.Substring(1);
						try
						{
							int ownedHvo = m_realDataCache.get_ObjFromGuid(new Guid(uid));
							hvos.Add(ownedHvo);
						}
						catch
						{
							// Invalid reference. Just remove the bogus hvo.
							// Since the id is added after the exception, it is effectively 'removed'.
							Debug.WriteLine("Bogus Id found.");
						}
					}
					m_realDataCache.CacheVecProp(kvp.Key.Hvo, (int)kvp.Key.Flid, hvos.ToArray(), hvos.Count);
				}
				m_delayedVecterReferences.Clear();
#if DEBUG
				end = DateTime.Now;
				span = new TimeSpan(end.Ticks - start.Ticks);
				totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
					span.Hours.ToString(), span.Minutes.ToString(), span.Seconds.ToString(), span.Milliseconds.ToString());
				Debug.WriteLine("Time to load main Cache: " + totalTime);
				start = end;

				Debug.WriteLine(String.Format("Number of objects cached: {0}", (m_realDataCache.NextHvo - 1).ToString()));
				//memory = objectBrowser..PrivateMemorySize64;
				//Debug.WriteLine(String.Format("Memory used (cache loaded): {0}.", memory.ToString()));
#endif
			}
			finally
			{
				m_realDataCache.CheckWithMDC = true;
			}
			return m_realDataCache;
		}
Exemple #4
0
        /// <summary>
        /// Create a RealDataCache object, and laod it with metadata and real data.
        /// </summary>
        /// <param name="metadataPathname"></param>
        /// <param name="realDataPathname"></param>
        /// <param name="objects"></param>
        /// <returns></returns>
        public RealDataCache LoadCache(string metadataPathname, string realDataPathname, Dictionary <int, uint> objects)
        {
            CheckDisposed();

            m_realDataCache = new RealDataCache();
            m_realDataCache.CheckWithMDC = false;

            try
            {
#if DEBUG
                //Process objectBrowser = Process.GetCurrentProcess();
                //long memory = objectBrowser.PrivateMemorySize64;
                //Debug.WriteLine(String.Format("Memory used (start load): {0}.", memory.ToString()));

                DateTime start = DateTime.Now;
#endif
                m_metaDataCache = new MetaDataCache();
                m_metaDataCache.InitXml(metadataPathname, true);
                m_realDataCache.MetaDataCache = m_metaDataCache;
#if DEBUG
                DateTime end       = DateTime.Now;
                TimeSpan span      = new TimeSpan(end.Ticks - start.Ticks);
                string   totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
                                                   span.Hours.ToString(), span.Minutes.ToString(), span.Seconds.ToString(), span.Milliseconds.ToString());
                Debug.WriteLine("Time to load MDC: " + totalTime);
                start = end;
                //memory = objectBrowser.PrivateMemorySize64;
                //Debug.WriteLine(String.Format("Memory used (loaded MDC load): {0}.", memory.ToString()));
#endif

                XmlDocument doc = new XmlDocument();
                doc.Load(realDataPathname);
#if DEBUG
                end       = DateTime.Now;
                span      = new TimeSpan(end.Ticks - start.Ticks);
                totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
                                          span.Hours.ToString(), span.Minutes.ToString(), span.Seconds.ToString(), span.Milliseconds.ToString());
                Debug.WriteLine("Time to load XML: " + totalTime);
                start = end;
                //memory = objectBrowser.PrivateMemorySize64;
                //Debug.WriteLine(String.Format("Memory used (loaded data XML): {0}.", memory.ToString()));
#endif

                // Load Writing Systems first.
                int  ord = 0;
                int  hvo;
                uint clid = 0;
                {
                    XmlNodeList wsNodes = doc.DocumentElement.SelectNodes("LgWritingSystem");
                    uint        flid    = m_metaDataCache.GetFieldId("LgWritingSystem", "ICULocale", false);
                    // We need a full list of ints and strings for Wses,
                    // before we can load string data,
                    // so cache the barebones first.
                    foreach (XmlNode wsNode in wsNodes)
                    {
                        hvo = BootstrapWs(wsNode, flid, out clid, objects);
                    }
                    foreach (XmlNode wsNode in wsNodes)
                    {
                        string uid = wsNode.Attributes["id"].Value.Substring(1);
                        hvo = m_realDataCache.get_ObjFromGuid(new Guid(uid));
                        LoadObject(wsNode, hvo, clid, objects);
                    }
                }
                // Now load other ownerless objects, except LangProject and Wses.
                foreach (XmlNode otherOwnerlessNode in doc.DocumentElement.ChildNodes)
                {
                    if (otherOwnerlessNode.Name != "LangProject" && otherOwnerlessNode.Name != "LgWritingSystem")
                    {
                        hvo = LoadCmObjectProperties(otherOwnerlessNode, 0, 0, ord, out clid, objects);
                        LoadObject(otherOwnerlessNode, hvo, clid, objects);
                    }
                }
                // Now load LangProject
                XmlNode langProjectNode = doc.DocumentElement.SelectSingleNode("LangProject");
                hvo = LoadCmObjectProperties(langProjectNode, 0, 0, ord, out clid, objects);
                LoadObject(langProjectNode, hvo, clid, objects);

                // Set references
                // Set atomic references
                foreach (KeyValuePair <HvoFlidKey, XmlNode> kvp in m_delayedAtomicReferences)
                {
                    string uid = kvp.Value.Attributes["target"].Value.Substring(1);
                    try
                    {
                        int hvoTarget = m_realDataCache.get_ObjFromGuid(new Guid(uid));
                        m_realDataCache.CacheObjProp(kvp.Key.Hvo, (int)kvp.Key.Flid, hvoTarget);
                    }
                    catch
                    {
                        // Invalid reference. Just clear the cache in case there is a save.
                        m_realDataCache.SetObjProp(kvp.Key.Hvo, (int)kvp.Key.Flid, 0);
                    }
                }
                //// Remove all items from m_delayedAtomicReferences that are in handledRefs.
                //// Theory has it that m_delayedAtomicReferences should then be empty.
                m_delayedAtomicReferences.Clear();

                // Set vector (col or seq) references.
                foreach (KeyValuePair <HvoFlidKey, List <XmlNode> > kvp in m_delayedVecterReferences)
                {
                    List <int> hvos = new List <int>();
                    foreach (XmlNode obj in kvp.Value)
                    {
                        string uid = obj.Attributes["target"].Value.Substring(1);
                        try
                        {
                            int ownedHvo = m_realDataCache.get_ObjFromGuid(new Guid(uid));
                            hvos.Add(ownedHvo);
                        }
                        catch
                        {
                            // Invalid reference. Just remove the bogus hvo.
                            // Since the id is added after the exception, it is effectively 'removed'.
                            Debug.WriteLine("Bogus Id found.");
                        }
                    }
                    m_realDataCache.CacheVecProp(kvp.Key.Hvo, (int)kvp.Key.Flid, hvos.ToArray(), hvos.Count);
                }
                m_delayedVecterReferences.Clear();
#if DEBUG
                end       = DateTime.Now;
                span      = new TimeSpan(end.Ticks - start.Ticks);
                totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
                                          span.Hours.ToString(), span.Minutes.ToString(), span.Seconds.ToString(), span.Milliseconds.ToString());
                Debug.WriteLine("Time to load main Cache: " + totalTime);
                start = end;

                Debug.WriteLine(String.Format("Number of objects cached: {0}", (m_realDataCache.NextHvo - 1).ToString()));
                //memory = objectBrowser..PrivateMemorySize64;
                //Debug.WriteLine(String.Format("Memory used (cache loaded): {0}.", memory.ToString()));
#endif
            }
            finally
            {
                m_realDataCache.CheckWithMDC = true;
            }
            return(m_realDataCache);
        }
Exemple #5
0
        /// <summary>
        /// Create a RealDataCache object, and laod it with metadata and real data.
        /// </summary>
        /// <param name="metadataPathname"></param>
        /// <param name="realDataPathname"></param>
        /// <param name="objects"></param>
        /// <returns></returns>
        public ISilDataAccess LoadCache(string metadataPathname, string realDataPathname, Dictionary <int, int> objects)
        {
            CheckDisposed();

            m_realDataCache = new RealDataCache {
                CheckWithMDC = false, TsStrFactory = TsStringUtils.TsStrFactory
            };

            try
            {
#if DEBUG
                //Process objectBrowser = Process.GetCurrentProcess();
                //long memory = objectBrowser.PrivateMemorySize64;
                //Debug.WriteLine(String.Format("Memory used (start load): {0}.", memory.ToString()));

                DateTime start = DateTime.Now;
#endif
                m_metaDataCache = new MetaDataCache();
                m_metaDataCache.InitXml(metadataPathname, true);
                m_realDataCache.MetaDataCache = m_metaDataCache;
#if DEBUG
                var end       = DateTime.Now;
                var span      = new TimeSpan(end.Ticks - start.Ticks);
                var totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
                                              span.Hours, span.Minutes, span.Seconds, span.Milliseconds);
                Debug.WriteLine("Time to load MDC: " + totalTime);
                start = end;
                //memory = objectBrowser.PrivateMemorySize64;
                //Debug.WriteLine(String.Format("Memory used (loaded MDC load): {0}.", memory.ToString()));
#endif

                var doc = new XmlDocument();
                doc.Load(realDataPathname);
#if DEBUG
                end       = DateTime.Now;
                span      = new TimeSpan(end.Ticks - start.Ticks);
                totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
                                          span.Hours, span.Minutes, span.Seconds, span.Milliseconds);
                Debug.WriteLine("Time to load XML: " + totalTime);
                start = end;
                //memory = objectBrowser.PrivateMemorySize64;
                //Debug.WriteLine(String.Format("Memory used (loaded data XML): {0}.", memory.ToString()));
#endif
                int       hvo, clid = 0;
                const int ord = 0;

                // First load all objects as if they were ownerless, except top-level objects.
                foreach (XmlNode ownedNode in doc.DocumentElement.ChildNodes)
                {
                    if (ownedNode.Attributes.GetNamedItem("owner").Value == "none")
                    {
                        continue;
                    }

                    hvo = LoadCmObjectProperties(ownedNode, 0, 0, ord, out clid, objects);
                    LoadObject(ownedNode, hvo, clid, objects);
                }
                // Now load all owned objects
                //XmlNode langProjectNode = doc.DocumentElement.SelectSingleNode("LangProject");
                //hvo = LoadCmObjectProperties(langProjectNode, 0, 0, ord, out clid, objects);
                //LoadObject(langProjectNode, hvo, clid, objects);
                foreach (XmlNode unownedNode in doc.DocumentElement.ChildNodes)
                {
                    if (unownedNode.Attributes.GetNamedItem("owner").Value == "none")
                    {
                        hvo = LoadCmObjectProperties(unownedNode, 0, 0, ord, out clid, objects);
                        LoadObject(unownedNode, hvo, clid, objects);
                    }
                }

                // Set references
                // Set atomic references
                foreach (var kvp in m_delayedAtomicReferences)
                {
                    var id = kvp.Value.Attributes["target"].Value.Substring(1);
                    try
                    {
                        var hvoTarget = m_realDataCache.get_ObjFromGuid(new Guid(id));
                        m_realDataCache.CacheObjProp(kvp.Key.Hvo, kvp.Key.Flid, hvoTarget);
                    }
                    catch
                    {
                        // Invalid reference. Just clear the cache in case there is a save.
                        m_realDataCache.SetObjProp(kvp.Key.Hvo, kvp.Key.Flid, 0);
                    }
                }
                //// Remove all items from m_delayedAtomicReferences that are in handledRefs.
                //// Theory has it that m_delayedAtomicReferences should then be empty.
                m_delayedAtomicReferences.Clear();

                // Set vector (col or seq) references.
                foreach (var kvp in m_delayedVecterReferences)
                {
                    var hvos = new List <int>();
                    foreach (XmlNode obj in kvp.Value)
                    {
                        var id = obj.Attributes["target"].Value.Substring(1);
                        try
                        {
                            var ownedHvo = m_realDataCache.get_ObjFromGuid(new Guid(id));
                            hvos.Add(ownedHvo);
                        }
                        catch
                        {
                            // Invalid reference. Just remove the bogus hvo.
                            // Since the id is added after the exception, it is effectively 'removed'.
                            Debug.WriteLine("Bogus Id found.");
                        }
                    }
                    m_realDataCache.CacheVecProp(kvp.Key.Hvo, kvp.Key.Flid, hvos.ToArray(), hvos.Count);
                }
                m_delayedVecterReferences.Clear();
#if DEBUG
                end       = DateTime.Now;
                span      = new TimeSpan(end.Ticks - start.Ticks);
                totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
                                          span.Hours, span.Minutes, span.Seconds, span.Milliseconds);
                Debug.WriteLine("Time to load main Cache: " + totalTime);

                Debug.WriteLine(String.Format("Number of objects cached: {0}", (m_realDataCache.NextHvo - 1)));
                //memory = objectBrowser..PrivateMemorySize64;
                //Debug.WriteLine(String.Format("Memory used (cache loaded): {0}.", memory.ToString()));
#endif
            }
            finally
            {
                m_realDataCache.CheckWithMDC = true;
            }
            return(m_realDataCache);
        }
Exemple #6
0
        public void Setup()
        {
            // Create the following:
            // - part and layout inventories
            // - metadata cache
            // - DataAccess cache
            // - collection of columns to display.

            // We want a MetaDataCache that knows about
            // - LexEntry.Senses, Msas, CitationForm, Bibliography, Etymology
            // - LexSense.SemanticDomains, SenseType, Status, gloss
            // - CmPossibility Name, abbr
            // - MoMorphSynAnalysis
            // - MoStemMsa
            // - MoDerivationalMsa
            m_mdc = FwMetaDataCacheClass.Create();
            string m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory,
                                              @"Common\Controls\XmlViews\XmlViewsTests\SampleCm.xml");

            m_mdc.InitXml(m_sTestPath, true);

            // We want ISilDataAccess with:
            // - LexEntry (1) with no senses and one MSA (2)
            // - LexEntry (4) with one sense (5) and no MSA
            // - LexEntry (6) with three senses (7, 8, 9) and two MSAs (10, 11)
            // - sense(5) with no semantic domains
            // - senses with one SD (7->30, 8->31)
            // - sense with three SDs, one the same as the first (9->30, 31, 32)
            // - MoStemMsa (2, 11)
            // - MoDerivationalMsa (10)
            m_cda = VwCacheDaClass.Create();
            m_sda = m_cda as ISilDataAccess;
            m_wsf = LgWritingSystemFactoryClass.Create();
            m_sda.WritingSystemFactory = m_wsf;
            SimpleDataParser parser = new SimpleDataParser(m_mdc, m_cda);

            parser.Parse(Path.Combine(DirectoryFinder.FwSourceDirectory,
                                      @"Common\Controls\XmlViews\XmlViewsTests\SampleData.xml"));
            int wsEn = m_wsf.GetWsFromStr("en");

            // These are mainly to check out the parser.
            Assert.AreEqual(3, m_sda.get_ObjectProp(2, 23011), "part of speech of an MoStemMsa");
            Assert.AreEqual(2, m_sda.get_VecItem(1, 2009, 0), "owned msa");
            Assert.AreEqual("noun", m_sda.get_MultiStringAlt(3, 7003, wsEn).Text, "got ms property");
            Assert.AreEqual(9, m_sda.get_VecItem(6, 2010, 2), "3rd sense");
            Assert.AreEqual(31, m_sda.get_VecItem(9, 21016, 1), "2nd semantic domain");

            // Columns includes
            // - CitationForm (string inside span)
            // - Bibliography (string not in span)
            // - Sense glosses (string in para in seq, nested in column element)
            // - Semantic domains (pair of strings in para in seq in seq, using layout refs)
            // - MSAs (simplified, but polymorphic with one having <choice> and one <obj> to CmPossibility
            XmlDocument docColumns = new XmlDocument();

            docColumns.Load(Path.Combine(DirectoryFinder.FwSourceDirectory,
                                         @"Common\Controls\XmlViews\XmlViewsTests\TestColumns.xml"));
            m_columnList = docColumns.DocumentElement.ChildNodes;

            // Parts just has what those columns need.
            string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory,
                                                @"Common\Controls\XmlViews\XmlViewsTests");
            Dictionary <string, string[]> keyAttrs = new Dictionary <string, string[]>();

            keyAttrs["layout"] = new string[] { "class", "type", "name" };
            keyAttrs["group"]  = new string[] { "label" };
            keyAttrs["part"]   = new string[] { "ref" };


            // Currently there are no specialized layout files that match.
            m_layoutInventory = new Inventory(new string[] { partDirectory },
                                              "*Layouts.xml", "/LayoutInventory/*", keyAttrs);

            keyAttrs         = new Dictionary <string, string[]>();
            keyAttrs["part"] = new string[] { "id" };

            m_partInventory = new Inventory(new string[] { partDirectory },
                                            "TestParts.xml", "/PartInventory/bin/*", keyAttrs);
            if (m_layouts != null)
            {
                m_layouts.Dispose();
            }
            m_layouts = new LayoutCache(m_mdc, m_layoutInventory, m_partInventory);
        }
		/// <summary>
		/// Create a RealDataCache object, and laod it with metadata and real data.
		/// </summary>
		/// <param name="metadataPathname"></param>
		/// <param name="realDataPathname"></param>
		/// <param name="objects"></param>
		/// <returns></returns>
		public ISilDataAccess LoadCache(string metadataPathname, string realDataPathname, Dictionary<int, int> objects)
		{
			CheckDisposed();

			m_realDataCache = new RealDataCache {CheckWithMDC = false};

			try
			{
#if DEBUG
				//Process objectBrowser = Process.GetCurrentProcess();
				//long memory = objectBrowser.PrivateMemorySize64;
				//Debug.WriteLine(String.Format("Memory used (start load): {0}.", memory.ToString()));

				DateTime start = DateTime.Now;
#endif
				m_metaDataCache = new MetaDataCache();
				m_metaDataCache.InitXml(metadataPathname, true);
				m_realDataCache.MetaDataCache = m_metaDataCache;
#if DEBUG
				var end = DateTime.Now;
				var span = new TimeSpan(end.Ticks - start.Ticks);
				var totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
					span.Hours, span.Minutes, span.Seconds, span.Milliseconds);
				Debug.WriteLine("Time to load MDC: " + totalTime);
				start = end;
				//memory = objectBrowser.PrivateMemorySize64;
				//Debug.WriteLine(String.Format("Memory used (loaded MDC load): {0}.", memory.ToString()));
#endif

				var doc = new XmlDocument();
				doc.Load(realDataPathname);
#if DEBUG
				end = DateTime.Now;
				span = new TimeSpan(end.Ticks - start.Ticks);
				totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
					span.Hours, span.Minutes, span.Seconds, span.Milliseconds);
				Debug.WriteLine("Time to load XML: " + totalTime);
				start = end;
				//memory = objectBrowser.PrivateMemorySize64;
				//Debug.WriteLine(String.Format("Memory used (loaded data XML): {0}.", memory.ToString()));
#endif
				int hvo, clid = 0;
				const int ord = 0;

				// First load all objects as if they were ownerless, except top-level objects.
				foreach (XmlNode ownedNode in doc.DocumentElement.ChildNodes)
				{
					if (ownedNode.Attributes.GetNamedItem("owner").Value == "none")
						continue;

					hvo = LoadCmObjectProperties(ownedNode, 0, 0, ord, out clid, objects);
					LoadObject(ownedNode, hvo, clid, objects);
				}
				// Now load all owned objects
				//XmlNode langProjectNode = doc.DocumentElement.SelectSingleNode("LangProject");
				//hvo = LoadCmObjectProperties(langProjectNode, 0, 0, ord, out clid, objects);
				//LoadObject(langProjectNode, hvo, clid, objects);
				foreach (XmlNode unownedNode in doc.DocumentElement.ChildNodes)
				{
					if (unownedNode.Attributes.GetNamedItem("owner").Value == "none")
					{
						hvo = LoadCmObjectProperties(unownedNode, 0, 0, ord, out clid, objects);
						LoadObject(unownedNode, hvo, clid, objects);
					}
				}

				// Set references
				// Set atomic references
				foreach (var kvp in m_delayedAtomicReferences)
				{
					var id = kvp.Value.Attributes["target"].Value.Substring(1);
					try
					{
						var hvoTarget = m_realDataCache.get_ObjFromGuid(new Guid(id));
						m_realDataCache.CacheObjProp(kvp.Key.Hvo, kvp.Key.Flid, hvoTarget);
					}
					catch
					{
						// Invalid reference. Just clear the cache in case there is a save.
						m_realDataCache.SetObjProp(kvp.Key.Hvo, kvp.Key.Flid, 0);
					}
				}
				//// Remove all items from m_delayedAtomicReferences that are in handledRefs.
				//// Theory has it that m_delayedAtomicReferences should then be empty.
				m_delayedAtomicReferences.Clear();

				// Set vector (col or seq) references.
				foreach (var kvp in m_delayedVecterReferences)
				{
					var hvos = new List<int>();
					foreach (XmlNode obj in kvp.Value)
					{
						var id = obj.Attributes["target"].Value.Substring(1);
						try
						{
							var ownedHvo = m_realDataCache.get_ObjFromGuid(new Guid(id));
							hvos.Add(ownedHvo);
						}
						catch
						{
							// Invalid reference. Just remove the bogus hvo.
							// Since the id is added after the exception, it is effectively 'removed'.
							Debug.WriteLine("Bogus Id found.");
						}
					}
					m_realDataCache.CacheVecProp(kvp.Key.Hvo, kvp.Key.Flid, hvos.ToArray(), hvos.Count);
				}
				m_delayedVecterReferences.Clear();
#if DEBUG
				end = DateTime.Now;
				span = new TimeSpan(end.Ticks - start.Ticks);
				totalTime = String.Format("Hours: {0}, Minutes: {1}, Seconds: {2}, Millseconds: {3}",
					span.Hours, span.Minutes, span.Seconds, span.Milliseconds);
				Debug.WriteLine("Time to load main Cache: " + totalTime);

				Debug.WriteLine(String.Format("Number of objects cached: {0}", (m_realDataCache.NextHvo - 1)));
				//memory = objectBrowser..PrivateMemorySize64;
				//Debug.WriteLine(String.Format("Memory used (cache loaded): {0}.", memory.ToString()));
#endif
			}
			finally
			{
				m_realDataCache.CheckWithMDC = true;
			}
			return m_realDataCache;
		}
		public void Setup()
		{
			// Create the following:
			// - part and layout inventories
			// - metadata cache
			// - DataAccess cache
			// - collection of columns to display.

			// We want a MetaDataCache that knows about
			// - LexEntry.Senses, Msas, CitationForm, Bibliography, Etymology
			// - LexSense.SemanticDomains, SenseType, Status, gloss
			// - CmPossibility Name, abbr
			// - MoMorphSynAnalysis
			// - MoStemMsa
			// - MoDerivationalMsa
			m_mdc = FwMetaDataCacheClass.Create();
			string m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory,
				@"Common\Controls\XmlViews\XmlViewsTests\SampleCm.xml");
			m_mdc.InitXml(m_sTestPath, true);

			// We want ISilDataAccess with:
			// - LexEntry (1) with no senses and one MSA (2)
			// - LexEntry (4) with one sense (5) and no MSA
			// - LexEntry (6) with three senses (7, 8, 9) and two MSAs (10, 11)
			// - sense(5) with no semantic domains
			// - senses with one SD (7->30, 8->31)
			// - sense with three SDs, one the same as the first (9->30, 31, 32)
			// - MoStemMsa (2, 11)
			// - MoDerivationalMsa (10)
			m_cda = VwCacheDaClass.Create();
			m_sda = m_cda as ISilDataAccess;
			m_wsf = LgWritingSystemFactoryClass.Create();
			m_sda.WritingSystemFactory = m_wsf;
			SimpleDataParser parser = new SimpleDataParser(m_mdc, m_cda);

			parser.Parse(Path.Combine(DirectoryFinder.FwSourceDirectory,
				@"Common\Controls\XmlViews\XmlViewsTests\SampleData.xml"));
			int wsEn = m_wsf.GetWsFromStr("en");
			// These are mainly to check out the parser.
			Assert.AreEqual(3, m_sda.get_ObjectProp(2, 23011), "part of speech of an MoStemMsa");
			Assert.AreEqual(2, m_sda.get_VecItem(1, 2009, 0), "owned msa");
			Assert.AreEqual("noun", m_sda.get_MultiStringAlt(3, 7003, wsEn).Text, "got ms property");
			Assert.AreEqual(9, m_sda.get_VecItem(6, 2010, 2), "3rd sense");
			Assert.AreEqual(31, m_sda.get_VecItem(9, 21016, 1), "2nd semantic domain");

			// Columns includes
			// - CitationForm (string inside span)
			// - Bibliography (string not in span)
			// - Sense glosses (string in para in seq, nested in column element)
			// - Semantic domains (pair of strings in para in seq in seq, using layout refs)
			// - MSAs (simplified, but polymorphic with one having <choice> and one <obj> to CmPossibility
			XmlDocument docColumns = new XmlDocument();
			docColumns.Load(Path.Combine(DirectoryFinder.FwSourceDirectory,
				@"Common\Controls\XmlViews\XmlViewsTests\TestColumns.xml"));
			m_columnList = docColumns.DocumentElement.ChildNodes;

			// Parts just has what those columns need.
			string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory,
				@"Common\Controls\XmlViews\XmlViewsTests");
			Dictionary<string, string[]> keyAttrs = new Dictionary<string, string[]>();
			keyAttrs["layout"] = new string[] {"class", "type", "name" };
			keyAttrs["group"] = new string[] {"label"};
			keyAttrs["part"] = new string[] {"ref"};


			// Currently there are no specialized layout files that match.
			m_layoutInventory = new Inventory(new string[] {partDirectory},
				"*Layouts.xml", "/LayoutInventory/*", keyAttrs);

			keyAttrs = new Dictionary<string, string[]>();
			keyAttrs["part"] = new string[] {"id"};

			m_partInventory = new Inventory(new string[] {partDirectory},
				"TestParts.xml", "/PartInventory/bin/*", keyAttrs);
			if (m_layouts != null)
				m_layouts.Dispose();
			m_layouts = new LayoutCache(m_mdc, m_layoutInventory, m_partInventory);
		}