private void TestFeatureStructureContent(IFsFeatStruc featStruct)
        {
            IFdoOwningCollection <IFsFeatureSpecification> specCol = featStruct.FeatureSpecsOC;

            Assert.AreEqual(1, specCol.Count, "Count of top level feature specs");
            foreach (IFsFeatureSpecification spec in specCol)
            {
                IFsComplexValue complex = spec as IFsComplexValue;
                Assert.IsNotNull(complex, "complex feature value is null and should not be");
                Assert.AreEqual("subject agreement", complex.FeatureRA.Name.AnalysisDefaultWritingSystem.Text, "Expected complex feature name");
                IFsFeatStruc fsNested = complex.ValueOA as IFsFeatStruc;
                IFdoOwningCollection <IFsFeatureSpecification> fsNestedCol = fsNested.FeatureSpecsOC;
                Assert.AreEqual(2, fsNestedCol.Count, "Nested fs has one feature");
                foreach (IFsFeatureSpecification specNested in fsNestedCol)
                {
                    IFsClosedValue closed = specNested as IFsClosedValue;
                    Assert.IsNotNull(closed, "closed feature value is null and should not be");
                    if (!(((closed.FeatureRA.Name.AnalysisDefaultWritingSystem.Text == "gender") &&
                           (closed.ValueRA.Name.AnalysisDefaultWritingSystem.Text == "feminine gender")) ||
                          ((closed.FeatureRA.Name.AnalysisDefaultWritingSystem.Text == "person") &&
                           (closed.ValueRA.Name.AnalysisDefaultWritingSystem.Text == "first person"))))
                    {
                        Assert.Fail("Unexpected value found: {0}:{1}",
                                    closed.FeatureRA.Name.AnalysisDefaultWritingSystem.Text,
                                    closed.ValueRA.Name.AnalysisDefaultWritingSystem.Text);
                    }
                }
            }
        }
        private void CreateFeatStruc(IFsFeatStrucType type, IFsFeatStruc fs, FS featVals)
        {
            fs.TypeRA = type;
            foreach (KeyValuePair <IFsFeatDefn, object> featVal in featVals)
            {
                var closedFeat = featVal.Key as IFsClosedFeature;
                if (closedFeat != null)
                {
                    var            sym = (IFsSymFeatVal)featVal.Value;
                    IFsClosedValue cv  = Cache.ServiceLocator.GetInstance <IFsClosedValueFactory>().Create();
                    fs.FeatureSpecsOC.Add(cv);
                    cv.FeatureRA = closedFeat;
                    cv.ValueRA   = sym;
                }
                else
                {
                    var             complexFeat = (IFsComplexFeature)featVal.Key;
                    IFsComplexValue cv          = Cache.ServiceLocator.GetInstance <IFsComplexValueFactory>().Create();
                    fs.FeatureSpecsOC.Add(cv);

                    IFsFeatStruc childFS = Cache.ServiceLocator.GetInstance <IFsFeatStrucFactory>().Create();
                    cv.FeatureRA = complexFeat;
                    cv.ValueOA   = childFS;
                    CreateFeatStruc(complexFeat.TypeRA, childFS, (FS)featVal.Value);
                }
            }
        }
Exemple #3
0
        protected void CreateFeatureStructureNodes(XmlDocument doc, XmlNode msaNode, IFsFeatStruc fs, int id, string sFSName)
        {
            if (fs == null)
            {
                return;
            }
            XmlNode fsNode = CreateXmlElement(doc, sFSName, msaNode);

            CreateXmlAttribute(doc, "id", id.ToString(), fsNode);
            foreach (IFsFeatureSpecification spec in fs.FeatureSpecsOC)
            {
                XmlNode feature = CreateXmlElement(doc, "feature", fsNode);
                XmlNode name    = CreateXmlElement(doc, "name", feature);
                name.InnerText = spec.FeatureRA.Abbreviation.BestAnalysisAlternative.Text;
                XmlNode        fvalue = CreateXmlElement(doc, "value", feature);
                IFsClosedValue cv     = spec as IFsClosedValue;
                if (cv != null)
                {
                    fvalue.InnerText = cv.ValueRA.Abbreviation.BestAnalysisAlternative.Text;
                }
                else
                {
                    IFsComplexValue complex = spec as IFsComplexValue;
                    if (complex == null)
                    {
                        continue;                         // skip this one since we're not dealing with it yet
                    }
                    IFsFeatStruc nestedFs = complex.ValueOA as IFsFeatStruc;
                    if (nestedFs != null)
                    {
                        CreateFeatureStructureNodes(doc, fvalue, nestedFs, 0, "fs");
                    }
                }
            }
        }
        private void AddNode(IFsFeatureSpecification spec, FeatureTreeNode parentNode)
        {
            IFsFeatDefn        defn = spec.FeatureRA;
            TreeNodeCollection col;

            if (parentNode == null)
            {
                col = Nodes;
            }
            else
            {
                col = parentNode.Nodes;
            }
            IFsClosedValue closed = spec as IFsClosedValue;

            if (closed != null)
            {
                foreach (FeatureTreeNode node in col)
                {
                    if (defn.Hvo == node.Hvo)
                    {                     // already there (which is to be expected); see if its value is, too
                        AddNodeFromFS(closed.ValueRA, node);
                        return;
                    }
                }
                // did not find the node, so add it and its value (not to be expected, but we'd better deal with it)
                FeatureTreeNode newNode = new FeatureTreeNode(defn.Name.AnalysisDefaultWritingSystem,
                                                              (int)ImageKind.feature, (int)ImageKind.feature, defn.Hvo, FeatureTreeNodeInfo.NodeKind.Closed);
                InsertNode(newNode, parentNode);
                IFsSymFeatVal val = closed.ValueRA;
                if (val != null)
                {
                    FeatureTreeNode newValueNode = new FeatureTreeNode(val.Name.AnalysisDefaultWritingSystem,
                                                                       (int)ImageKind.radioSelected, (int)ImageKind.radioSelected, val.Hvo, FeatureTreeNodeInfo.NodeKind.SymFeatValue);
                    newValueNode.Chosen = true;
                    InsertNode(newValueNode, newNode);
                }
            }
            IFsComplexValue complex = spec as IFsComplexValue;

            if (complex != null)
            {
                foreach (FeatureTreeNode node in col)
                {
                    if (defn.Hvo == node.Hvo)
                    {                     // already there (which is to be expected); see if its value is, too
                        AddNode((IFsFeatStruc)complex.ValueOA, node);
                        return;
                    }
                }
                // did not find the node, so add it and its value (not to be expected, but we'd better deal with it)
                FeatureTreeNode newNode = new FeatureTreeNode(defn.Name.AnalysisDefaultWritingSystem,
                                                              (int)ImageKind.complex, (int)ImageKind.complex, defn.Hvo, FeatureTreeNodeInfo.NodeKind.Complex);
                InsertNode(newNode, parentNode);
                AddNode((IFsFeatStruc)complex.ValueOA, newNode);
            }
        }
        /// <summary>
        /// Recursively builds the feature structure based on contents of treeview node path.
        /// It recurses back up the treeview node path to the top and then builds the feature structure
        /// as it goes back down.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="fs"></param>
        /// <returns></returns>
        private void BuildFeatureStructure(FeatureTreeNode node, ref IFsFeatStruc fs, ref IFsFeatureSpecification val)
        {
            if (node.Parent != null)
            {
                BuildFeatureStructure((FeatureTreeNode)node.Parent, ref fs, ref val);
            }
            switch (node.Kind)
            {
            case FeatureTreeNodeInfo.NodeKind.Complex:
                IFsComplexValue complex = fs.FindOrCreateComplexValue(node.Hvo);
                val = complex as FsComplexValue;
                val.FeatureRAHvo = node.Hvo;
                if (fs.TypeRA == null)
                {
                    // this is the type which contains the complex feature
                    fs.TypeRAHvo = FsFeatureSystem.GetTypeFromFsComplexFeature(m_cache, node.Hvo);
                }
                fs = (IFsFeatStruc)complex.ValueOA;
                if (fs.TypeRA == null)
                {
                    // this is the type of what's being embedded in the fs
                    IFsComplexFeature cf = val.FeatureRA as IFsComplexFeature;
                    if (cf != null)
                    {
                        fs.TypeRA = cf.TypeRA;
                    }
                }
                break;

            case FeatureTreeNodeInfo.NodeKind.Closed:
                val = (IFsClosedValue)fs.FindOrCreateClosedValue(node.Hvo);
                val.FeatureRAHvo = node.Hvo;
                break;

            case FeatureTreeNodeInfo.NodeKind.SymFeatValue:
                IFsClosedValue closed = val as IFsClosedValue;
                if (closed != null)
                {
                    closed.ValueRAHvo = node.Hvo;
                }
                break;

            default:
                break;                         // do nothing
            }
        }
Exemple #6
0
        public void AddComplexFeaturesToFeatureSystemAndThenToAFeatureStructure()
        {
            ILangProject lp = Cache.LangProject;

            Assert.IsNotNull(lp.MsFeatureSystemOA, "Expect a feature system to be present");

            // Set up the xml fs description
            XmlDocument doc      = new XmlDocument();
            string      sFileDir = Path.Combine(SIL.FieldWorks.Common.Utils.DirectoryFinder.FwSourceDirectory, @"FDO\FDOTests\TestData");
            string      sFile    = Path.Combine(sFileDir, "FeatureSystem2.xml");

            doc.Load(sFile);
            XmlNode itemNeut = doc.SelectSingleNode("//item[@id='vNeut']");

            // Add the feature for first time
            FsFeatureSystem.AddFeatureAsXml(Cache, itemNeut);
            IFsFeatureSystem msfs = lp.MsFeatureSystemOA;

            Assert.AreEqual(1, msfs.TypesOC.Count, "should have two types");
            Assert.AreEqual(2, msfs.FeaturesOC.Count, "should have two features");
            foreach (IFsFeatStrucType type in msfs.TypesOC)
            {
                string sName = type.Name.AnalysisDefaultWritingSystem;
                if (sName != "Subject agreement")
                {
                    Assert.Fail("Unexpected fs type found: {0}", sName);
                }
                Assert.AreEqual(1, type.FeaturesRS.Count, "Expect to have one feature in the type");
                IFsFeatDefn defn = (IFsFeatDefn)type.FeaturesRS.FirstItem;
                Assert.IsNotNull(defn, "first feature in type {0} is not null", sName);
                IFsComplexFeature complex = defn as IFsComplexFeature;
                if (complex != null)
                {
                    Assert.AreEqual("subject agreement", complex.Name.AnalysisDefaultWritingSystem, "Expect name of subject agreement");
                }
                IFsClosedFeature closed = defn as IFsClosedFeature;
                if (closed != null)
                {
                    Assert.AreEqual("gender", closed.Name.AnalysisDefaultWritingSystem, "Expect to have gender feature");
                    foreach (IFsSymFeatVal value in closed.ValuesOC)
                    {
                        Assert.AreEqual("neuter gender", value.Name.AnalysisDefaultWritingSystem, "Expect neuter value");
                    }
                }
            }
            foreach (IFsFeatDefn defn in msfs.FeaturesOC)
            {
                IFsComplexFeature complex = defn as IFsComplexFeature;
                if (complex != null)
                {
                    Assert.AreEqual("subject agreement", complex.Name.AnalysisDefaultWritingSystem, "Expect to have subject agreement feature");
                }
                IFsClosedFeature closed = defn as IFsClosedFeature;
                if (closed != null)
                {
                    Assert.AreEqual("gender", closed.Name.AnalysisDefaultWritingSystem, "Expect to have gender feature");
                    foreach (IFsSymFeatVal value in closed.ValuesOC)
                    {
                        Assert.AreEqual("neuter gender", value.Name.AnalysisDefaultWritingSystem, "Expect neuter value");
                    }
                }
            }
            // Now add a feature that differs only in value
            XmlNode itemFem = doc.SelectSingleNode("//item[@id='vFem']");

            FsFeatureSystem.AddFeatureAsXml(Cache, itemFem);
            Assert.AreEqual(1, msfs.TypesOC.Count, "should have two types");
            Assert.AreEqual(2, msfs.FeaturesOC.Count, "should have two features");
            foreach (IFsFeatStrucType type in msfs.TypesOC)
            {
                string sName = type.Name.AnalysisDefaultWritingSystem;
                if (sName != "Subject agreement")
                {
                    Assert.Fail("Unexpected fs type found: {0}", sName);
                }
            }
            foreach (IFsFeatDefn defn in msfs.FeaturesOC)
            {
                IFsComplexFeature complex = defn as IFsComplexFeature;
                if (complex != null)
                {
                    Assert.AreEqual("subject agreement", complex.Name.AnalysisDefaultWritingSystem, "Expect to have subject agreement feature");
                }
                IFsClosedFeature closed = defn as IFsClosedFeature;
                if (closed != null)
                {
                    Assert.AreEqual("gender", closed.Name.AnalysisDefaultWritingSystem, "Expect to have gender feature");
                    Assert.AreEqual(2, closed.ValuesOC.Count, "should have two values");
                    foreach (IFsSymFeatVal cv in closed.ValuesOC)
                    {
                        if (cv.Name.AnalysisDefaultWritingSystem != "neuter gender" &&
                            cv.Name.AnalysisDefaultWritingSystem != "feminine gender")
                        {
                            Assert.Fail("Unexpected value found: {0}", cv.Name.AnalysisDefaultWritingSystem);
                        }
                    }
                }
            }

            // now add to feature structure
            IPartOfSpeech pos = (IPartOfSpeech)lp.PartsOfSpeechOA.PossibilitiesOS.FirstItem;

            Assert.IsNotNull(pos, "Need one non-null pos");

            pos.DefaultFeaturesOA = new FsFeatStruc();
            IFsFeatStruc featStruct = pos.DefaultFeaturesOA;

            // Add the first feature
            featStruct.AddFeatureFromXml(Cache, itemNeut);
            Assert.AreEqual("sbj", featStruct.TypeRA.Abbreviation.AnalysisDefaultWritingSystem, "Expect type sbj");
            Assert.AreEqual(1, featStruct.FeatureSpecsOC.Count, "should have one feature spec");
            foreach (IFsFeatureSpecification fspec in featStruct.FeatureSpecsOC)
            {
                IFsComplexValue complex = fspec as IFsComplexValue;
                Assert.IsNotNull(complex, "Should have non-null complex feature value");
                IFsFeatStruc nestedFs = (IFsFeatStruc)complex.ValueOA;
                Assert.IsNotNull(nestedFs, "Should have non-null nested fs");
                foreach (IFsClosedValue cv in nestedFs.FeatureSpecsOC)
                {
                    Assert.AreEqual("gen", cv.FeatureRA.Abbreviation.AnalysisDefaultWritingSystem, "Expect to have gen feature name");
                    Assert.AreEqual("n", cv.ValueRA.Abbreviation.AnalysisDefaultWritingSystem, "Expect to have 'n' feature value");
                }
            }
            // Now add a feature that differs only in value; it should override the old one
            featStruct.AddFeatureFromXml(Cache, itemFem);
            Assert.AreEqual("sbj", featStruct.TypeRA.Abbreviation.AnalysisDefaultWritingSystem, "Expect type sbj");
            Assert.AreEqual(1, featStruct.FeatureSpecsOC.Count, "should have one feature spec");
            foreach (IFsFeatureSpecification fspec in featStruct.FeatureSpecsOC)
            {
                IFsComplexValue complex = fspec as IFsComplexValue;
                Assert.IsNotNull(complex, "Should have non-null complex feature value");
                IFsFeatStruc nestedFs = (IFsFeatStruc)complex.ValueOA;
                Assert.IsNotNull(nestedFs, "Should have non-null nested fs");
                foreach (IFsClosedValue cv in nestedFs.FeatureSpecsOC)
                {
                    if (cv.FeatureRA.Name.AnalysisDefaultWritingSystem != "gender" &&
                        cv.ValueRA.Name.AnalysisDefaultWritingSystem != "feminine gender")
                    {
                        Assert.Fail("Unexpected value found: {0}:{1}", cv.FeatureRA.Name.AnalysisDefaultWritingSystem,
                                    cv.ValueRA.Name.AnalysisDefaultWritingSystem);
                    }
                }
            }
            // Now add another feature
            XmlNode item1st = doc.SelectSingleNode("//item[@id='v1']");

            featStruct.AddFeatureFromXml(Cache, item1st);
            Assert.AreEqual("sbj", featStruct.TypeRA.Abbreviation.AnalysisDefaultWritingSystem, "Expect type sbj");
            Assert.AreEqual(1, featStruct.FeatureSpecsOC.Count, "should have one feature spec at top feature structure");
            foreach (IFsFeatureSpecification fspec in featStruct.FeatureSpecsOC)
            {
                IFsComplexValue complex = fspec as IFsComplexValue;
                Assert.IsNotNull(complex, "Should have non-null complex feature value");
                IFsFeatStruc nestedFs = (IFsFeatStruc)complex.ValueOA;
                Assert.IsNotNull(nestedFs, "Should have non-null nested fs");
                Assert.AreEqual(2, nestedFs.FeatureSpecsOC.Count, "should have two feature specs in nested feature structure");
                foreach (IFsClosedValue cv in nestedFs.FeatureSpecsOC)
                {
                    if (!(((cv.FeatureRA.Name.AnalysisDefaultWritingSystem == "gender") &&
                           (cv.ValueRA.Name.AnalysisDefaultWritingSystem == "feminine gender")) ||
                          ((cv.FeatureRA.Name.AnalysisDefaultWritingSystem == "person") &&
                           (cv.ValueRA.Name.AnalysisDefaultWritingSystem == "first person"))))
                    {
                        Assert.Fail("Unexpected value found: {0}:{1}", cv.FeatureRA.Name.AnalysisDefaultWritingSystem,
                                    cv.ValueRA.Name.AnalysisDefaultWritingSystem);
                    }
                }
            }
            // Update inflectable features on pos
            pos.AddInflectableFeatsFromXml(Cache, itemNeut);
            Assert.AreEqual(1, pos.InflectableFeatsRC.Count, "should have 1 inflectable feature in pos");
            foreach (IFsFeatDefn defn in pos.InflectableFeatsRC)
            {
                IFsComplexFeature complex = defn as IFsComplexFeature;
                if (complex != null)
                {
                    Assert.AreEqual("subject agreement", complex.Name.AnalysisDefaultWritingSystem, "expect to find subject agreement in pos inflectable features");
                }
            }
            // Check for correct ShortName string in complex
            Assert.AreEqual("1 f", featStruct.ShortName, "Incorrect ShortName for complex");
            // Check for correct LongName string in complex
            Assert.AreEqual("[sbj:[pers:1 gen:f]]", featStruct.LongName, "Incorrect LongName for complex");
            // Now add a closed feature not at the same level
            sFile = Path.Combine(sFileDir, "FeatureSystem3.xml");
            doc   = null;
            doc   = new XmlDocument();
            doc.Load(sFile);
            XmlNode itemAorist = doc.SelectSingleNode("//item[@id='xAor']");

            FsFeatureSystem.AddFeatureAsXml(Cache, itemAorist);
            pos.AddInflectableFeatsFromXml(Cache, itemAorist);
            featStruct.AddFeatureFromXml(Cache, itemAorist);
            // Check for correct LongName
            Assert.AreEqual("[asp:aor sbj:[pers:1 gen:f]]", featStruct.LongName, "Incorrect LongName for complex and closed");
            // Now add the features in the featurs struct in a different order
            pos.DefaultFeaturesOA = null;
            pos.DefaultFeaturesOA = new FsFeatStruc();
            featStruct            = pos.DefaultFeaturesOA;
            featStruct.AddFeatureFromXml(Cache, itemAorist);
            featStruct.AddFeatureFromXml(Cache, item1st);
            featStruct.AddFeatureFromXml(Cache, itemFem);
            // check for correct short name
            Assert.AreEqual("f 1 aor", featStruct.ShortName, "Incorrect ShortName for complex");
            // Check for correct LongName
            Assert.AreEqual("[sbj:[gen:f pers:1] asp:aor]", featStruct.LongName, "Incorrect LongName for complex and closed");
        }