/// <summary> /// Use the MetaDataCache and reflection to store the XML data if at all possible. /// </summary> /// <returns><c>true</c> if data was stored, <c>false</c> otherwise.</returns> private bool StoreUnanticipatedDataIfPossible(ICmObject obj, XmlReader xrdrSub) { try { var metaDataCache = obj.Cache.MetaDataCache as IFwMetaDataCacheManaged; if (metaDataCache == null) { return(false); } var flid = metaDataCache.GetFieldId(obj.GetType().Name, xrdrSub.Name, true); if (flid == 0) { return(false); } var type = metaDataCache.GetFieldType(flid); // REVIEW: how do we handle custom fields? Do we need to worry about those in this context? var prop = obj.GetType().GetProperty(xrdrSub.Name); if (prop == null) { return(false); } switch (type) { case (int)CellarPropertyType.MultiString: var ms = prop.GetValue(obj, null) as IMultiString; if (ms == null) { return(false); } SetMultiStringFromXml(xrdrSub, ms); return(true); case (int)CellarPropertyType.MultiUnicode: var mu = prop.GetValue(obj, null) as IMultiUnicode; if (mu == null) { return(false); } SetMultiUnicodeFromXml(xrdrSub, mu); return(true); default: // We don't know how to handle any other data types for now. The two above are the ones // that are relevant for translation anyway. return(false); } } catch { return(false); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Determines whether or not the specified property name of the specified object /// should be displayed. /// </summary> /// ------------------------------------------------------------------------------------ public static bool IsPropertyDisplayed(ICmObject cmObj, string propName) { if (s_showCmObjProps || !IsCmObjectProperty(propName)) { LCMClass cls; if (s_FDOClassesByType.TryGetValue(cmObj.GetType(), out cls)) { return(cls.IsPropertyDisplayed(propName)); } } return(false); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="ClassPropertySelector"/> class. /// </summary> /// ------------------------------------------------------------------------------------ public ClassPropertySelector(ICmObject obj) : this() { if (obj == null) return; foreach (FDOClass cls in cboClass.Items) { if (obj.GetType() == cls.ClassType) { cboClass.SelectedItem = cls; cboClass_SelectionChangeCommitted(null, null); } } }
public static void WriteMsaElement(this XmlWriter writer, FdoCache cache, string formID, string msaID, string type, string wordType) { // Irregulary inflected forms can have a combination MSA hvo: the LexEntry hvo, a period, and an index to the LexEntryRef Tuple <int, int> msaTuple = ProcessMsaHvo(msaID); ICmObject obj = cache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(msaTuple.Item1); switch (obj.GetType().Name) { default: throw new ApplicationException(String.Format("Invalid MSA type: {0}.", obj.GetType().Name)); case "MoStemMsa": WriteStemMsaXmlElement(writer, (IMoStemMsa)obj, Enumerable.Empty <ILexEntryRef>()); break; case "MoInflAffMsa": WriteInflectionClasses(writer, cache, int.Parse(formID, CultureInfo.InvariantCulture)); WriteInflMsaXmlElement(writer, (IMoInflAffMsa)obj, type); break; case "MoDerivAffMsa": WriteDerivMsaXmlElement(writer, (IMoDerivAffMsa)obj); break; case "MoUnclassifiedAffixMsa": WriteUnclassifedMsaXmlElement(writer, (IMoUnclassifiedAffixMsa)obj); break; case "LexEntry": // is an irregularly inflected form // get the MoStemMsa of its variant var entry = (ILexEntry)obj; if (entry.EntryRefsOS.Count > 0) { ILexEntryRef lexEntryRef = entry.EntryRefsOS[msaTuple.Item2]; ILexSense sense = MorphServices.GetMainOrFirstSenseOfVariant(lexEntryRef); WriteStemMsaXmlElement(writer, (IMoStemMsa)sense.MorphoSyntaxAnalysisRA, entry.VariantEntryRefs); } break; case "LexEntryInflType": // This is one of the null allomorphs we create when building the // input for the parser in order to still get the Word Grammar to have something in any // required slots in affix templates. WriteInflMsaForLexEntryInflType(writer, wordType, (ILexEntryInflType)obj); break; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="T:ClassPropertySelector"/> class. /// </summary> /// ------------------------------------------------------------------------------------ public ClassPropertySelector(ICmObject obj) : this() { if (obj == null) { return; } foreach (FDOClass cls in cboClass.Items) { if (obj.GetType() == cls.ClassType) { cboClass.SelectedItem = cls; cboClass_SelectionChangeCommitted(null, null); } } }
/// <summary> /// Calls the sort method. /// </summary> /// <param name="cmo">The object.</param> /// <param name="sortedFromEnd">if set to <c>true</c> [sorted from end].</param> /// <returns></returns> private string[] CallSortMethod(ICmObject cmo, bool sortedFromEnd) { Type typeCmo = cmo.GetType(); try { MethodInfo mi = typeCmo.GetMethod(m_sMethodName); if (mi == null) { return(null); } object obj; if (mi.GetParameters().Length == 2) { // Enhance JohnT: possibly we should seek to evaluate this every time, in case it is a magic WS like // "best vernacular". But interpreting those requires a flid, and we don't have one; indeed, the // method may retrieve information from several. So we may as well just accept that the fancy ones // won't work. if (m_ws == 0 && WritingSystemName != null) { m_ws = WritingSystemServices.InterpretWsLabel(m_cache, WritingSystemName, null, 0, 0, null); } obj = mi.Invoke(cmo, new object[] { sortedFromEnd, m_ws }); } else { obj = mi.Invoke(cmo, new object[] { sortedFromEnd }); } if (obj is string) { return new [] { (string)obj } } ; // otherwise assume it already is a string array. return((string[])obj); } catch (Exception) { return(null); } }
protected void CreateMsaXmlElement(XmlNode node, XmlDocument doc, XmlNode morphNode, string sHvo) { XmlNode attr; // morphname contains the hvo of the msa attr = node.SelectSingleNode(sHvo); if (attr != null) { ICmObject obj = CmObject.CreateFromDBObject(m_cache, Convert.ToInt32(attr.Value)); switch (obj.GetType().Name) { default: throw new ApplicationException(String.Format("Invalid MSA type: {0}.", obj.GetType().Name)); case "MoStemMsa": IMoStemMsa stemMsa = obj as IMoStemMsa; CreateStemMsaXmlElement(doc, morphNode, stemMsa); break; case "MoInflAffMsa": IMoInflAffMsa inflMsa = obj as IMoInflAffMsa; CreateInflectionClasses(doc, morphNode); CreateInflMsaXmlElement(doc, morphNode, inflMsa); break; case "MoDerivAffMsa": IMoDerivAffMsa derivMsa = obj as IMoDerivAffMsa; CreateDerivMsaXmlElement(doc, morphNode, derivMsa); break; case "MoUnclassifiedAffixMsa": IMoUnclassifiedAffixMsa unclassMsa = obj as IMoUnclassifiedAffixMsa; CreateUnclassifedMsaXmlElement(doc, morphNode, unclassMsa); break; } } }
internal static int GetFlidOfVectorFromName(string name, string owner, FdoCache cache, Mediator mediator, out ICmObject owningObject, ref string fontName, ref int typeSize) { owningObject = null; int realFlid = 0; switch (name) { default: // REVIEW (TimS): This code was added as a way to include information easier in // XCore. Is this a good idea or should we just add another case statement each // time a new name is needed? try { // ENHANCE (TimS): The same method of getting the flid could be done to // get the owner. switch (owner) { case "LangProject": owningObject = cache.LangProject; break; case "LexDb": owningObject = cache.LangProject.LexDbOA; break; case "RnResearchNbk": owningObject = cache.LangProject.ResearchNotebookOA; break; case "WordformInventory": owningObject = cache.LangProject.WordformInventoryOA; break; case "DsDiscourseData": owningObject = cache.LangProject.DiscourseDataOA; break; default: Debug.Assert(false, "Illegal owner specified for possibility list."); break; } IVwVirtualHandler vh = cache.VwCacheDaAccessor.GetVirtualHandlerName(owner, name); if (vh != null) { // get the flid for the virtual handler. realFlid = vh.Tag; } else { // real fields will have a FdoVector collection format FdoVector<ICmObject> collection = (FdoVector<ICmObject>)owningObject.GetType().InvokeMember(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, owningObject, null); realFlid = collection.Flid; } } catch { throw new ConfigurationException("The field '" + name + "' with owner '" + owner + "' has not been implemented in the switch statement " + "in RecordList.GetVectorFromName()."); } break; // Other supported stuff case "Entries": if (owner == "ReversalIndex") { // The null objects shouldn't happen, but LTB-846 indicates one did. if (cache.LangProject.LexDbOA.ReversalIndexesOC == null || cache.LangProject.LexDbOA.ReversalIndexesOC.HvoArray == null || cache.LangProject.LexDbOA.ReversalIndexesOC.HvoArray.Length == 0) { // invoke the Reversal listener to create the index for this invalid state Mediator msgMediator = (FwXApp.App != null ? ((XCore.XWindow)(FwXApp.App.ActiveMainWindow)).Mediator : null); msgMediator.SendMessage("InsertReversalIndex_FORCE", null); } if (cache.LangProject.LexDbOA.ReversalIndexesOC.HvoArray.Length > 0) { int hvo = cache.LangProject.LexDbOA.ReversalIndexesOC.HvoArray[0]; owningObject = ReversalIndex.CreateFromDBObject(cache, hvo); realFlid = (int)ReversalIndex.ReversalIndexTags.kflidEntries; } } else { owningObject = cache.LangProject.LexDbOA; realFlid = (int)LexDb.LexDbTags.kflidEntries; } break; case "Scripture_0_0_Content": // StText that is contents of first section of first book. try { IScrBook sb = cache.LangProject.TranslatedScriptureOA.ScriptureBooksOS[0]; IScrSection ss = sb.SectionsOS[0]; owningObject = ss.ContentOA; } catch (NullReferenceException) { Trace.Fail("Could not get the test Scripture object. Your language project might not have one (or their could have been some other error). Try TestLangProj."); throw; } realFlid = (int)StText.StTextTags.kflidParagraphs; break; case "Texts": owningObject = cache.LangProject; realFlid = (int)LangProject.LangProjectTags.kflidTexts; break; case "MsFeatureSystem": owningObject = cache.LangProject; realFlid = (int)LangProject.LangProjectTags.kflidMsFeatureSystem; break; // phonology case "Phonemes": owningObject = cache.LangProject.PhonologicalDataOA.PhonemeSetsOS[0]; realFlid = (int)PhPhonemeSet.PhPhonemeSetTags.kflidPhonemes; break; case "BoundaryMarkers": owningObject = cache.LangProject.PhonologicalDataOA.PhonemeSetsOS[0]; realFlid = (int)PhPhonemeSet.PhPhonemeSetTags.kflidBoundaryMarkers; break; case "Environments": owningObject = cache.LangProject.PhonologicalDataOA; realFlid = (int)PhPhonData.PhPhonDataTags.kflidEnvironments; break; case "NaturalClasses": owningObject = cache.LangProject.PhonologicalDataOA; realFlid = (int)PhPhonData.PhPhonDataTags.kflidNaturalClasses; fontName = cache.LangProject.DefaultAnalysisWritingSystemFont; typeSize = GetFontHeightFromStylesheet(cache, mediator, true); break; case "PhonologicalFeatures": owningObject = cache.LangProject.PhFeatureSystemOA; realFlid = (int)FsFeatureSystem.FsFeatureSystemTags.kflidFeatures; fontName = cache.LangProject.DefaultAnalysisWritingSystemFont; typeSize = GetFontHeightFromStylesheet(cache, mediator, true); break; case "PhonologicalRules": owningObject = cache.LangProject.PhonologicalDataOA; realFlid = (int)PhPhonData.PhPhonDataTags.kflidPhonRules; break; // morphology case "AdhocCoprohibitions": owningObject = cache.LangProject.MorphologicalDataOA; realFlid = (int)MoMorphData.MoMorphDataTags.kflidAdhocCoProhibitions; fontName = cache.LangProject.DefaultAnalysisWritingSystemFont; typeSize = GetFontHeightFromStylesheet(cache, mediator, true); break; case "CompoundRules": owningObject = cache.LangProject.MorphologicalDataOA; realFlid = (int)MoMorphData.MoMorphDataTags.kflidCompoundRules; fontName = cache.LangProject.DefaultAnalysisWritingSystemFont; typeSize = GetFontHeightFromStylesheet(cache, mediator, true); break; case "Features": owningObject = cache.LangProject.MsFeatureSystemOA; realFlid = (int)FsFeatureSystem.FsFeatureSystemTags.kflidFeatures; fontName = cache.LangProject.DefaultAnalysisWritingSystemFont; typeSize = GetFontHeightFromStylesheet(cache, mediator, true); break; case "FeatureTypes": owningObject = cache.LangProject.MsFeatureSystemOA; realFlid = (int)FsFeatureSystem.FsFeatureSystemTags.kflidTypes; fontName = cache.LangProject.DefaultAnalysisWritingSystemFont; typeSize = GetFontHeightFromStylesheet(cache, mediator, true); break; case "ProdRestrict": owningObject = cache.LangProject.MorphologicalDataOA; realFlid = (int)MoMorphData.MoMorphDataTags.kflidProdRestrict; fontName = cache.LangProject.DefaultAnalysisWritingSystemFont; typeSize = GetFontHeightFromStylesheet(cache, mediator, true); break; case "Problems": owningObject = cache.LangProject; realFlid = (int)LangProject.LangProjectTags.kflidAnnotations; fontName = cache.LangProject.DefaultAnalysisWritingSystemFont; typeSize = GetFontHeightFromStylesheet(cache, mediator, true); break; case "Wordforms": owningObject = cache.LangProject.WordformInventoryOA; realFlid = (int)SIL.FieldWorks.FDO.Ling.WordformInventory.WordformInventoryTags.kflidWordforms; break; case "ConcordanceWords": owningObject = cache.LangProject.WordformInventoryOA; realFlid = WordformInventory.ConcordanceWordformsFlid(cache); break; case "MatchingConcordanceItems": owningObject = cache.LangProject.WordformInventoryOA; realFlid = WordformInventory.MatchingConcordanceItemsFlid(cache); break; case "ReversalIndexes": { owningObject = cache.LangProject.LexDbOA; realFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "LexDb", "CurrentReversalIndices"); break; } //dependent properties case "Analyses": { IWordformInventory wfi = cache.LangProject.WordformInventoryOA; if (wfi != null) { //TODO: HACK! making it show the first one. if (wfi.WordformsOC.Count > 0) owningObject = CmObject.CreateFromDBObject(cache, wfi.WordformsOC.HvoArray[0]); } realFlid = (int)WfiWordform.WfiWordformTags.kflidAnalyses; break; } case "SemanticDomainList": owningObject = cache.LangProject.SemanticDomainListOA; realFlid = (int)SIL.FieldWorks.FDO.Cellar.CmPossibilityList.CmPossibilityListTags.kflidPossibilities; break; case "AllSenses": { owningObject = cache.LangProject.LexDbOA; realFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "LexDb", "AllSenses"); // Todo: something about initial sorting... break; } case "AllExampleSentenceTargets": { owningObject = cache.LangProject.LexDbOA; realFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "LexDb", "AllExampleSentenceTargets"); // Todo: something about initial sorting... break; } case "AllPossiblePronunciations": { owningObject = cache.LangProject.LexDbOA; realFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "LexDb", "AllPossiblePronunciations"); // Todo: something about initial sorting... break; } case "AllEntryRefs": { owningObject = cache.LangProject.LexDbOA; realFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "LexDb", "AllEntryRefs"); // Todo: something about initial sorting... break; } case "AllPossibleAllomorphs": { owningObject = cache.LangProject.LexDbOA; realFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "LexDb", "AllPossibleAllomorphs"); // Todo: something about initial sorting... break; } case "AllAllomorphsList": { owningObject = cache.LangProject.LexDbOA; realFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "LexDb", name); // Todo: something about initial sorting... break; } case "AllMLAnalysesClientIDs": // Fall through. case "AllAnalysesClientIDs": // Fall through. case "AllWordformClientIDs": // Fall through. case "AllSentenceClientIDs": // Fall through. case "AllCompoundRuleClientIDs": // Fall through. case "AllEntryClientIDs": // Fall through. case "AllSenseClientIDs": // Fall through. case "AllMSAClientIDs": { switch (owner) { case "PartOfSpeech": owningObject = cache.LangProject.PartsOfSpeechOA.PossibilitiesOS[0]; break; case "LexSense": int senseId; DbOps.ReadOneIntFromCommand(cache, "SELECT TOP 1 Id FROM LexSense", null, out senseId); if (senseId != 0) // Can happen with Concorder plug-in. See LT-7960. owningObject = LexSense.CreateFromDBObject(cache, senseId); break; } realFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, owner, name); // Todo: something about initial sorting... break; } } return realFlid; }
/// -------------------------------------------------------------------------------- /// <summary> /// Gets the property. /// </summary> /// <param name="target">The target.</param> /// <param name="property">The property.</param> /// <returns></returns> /// -------------------------------------------------------------------------------- protected object GetProperty(ICmObject target, string property) { Type type = target.GetType(); System.Reflection.PropertyInfo info = type.GetProperty(property, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy ); if (info == null) throw new ArgumentException("There is no public property named '" + property + "' in " + type.ToString() + ". Remember, properties often end in a multi-character suffix such as OA, OS, RA, RS, or Accessor."); return info.GetValue(target,null); }
private bool InitializeConcordanceSearch(ICmObject cmo, ITsString tssObj) { string sType = cmo.GetType().Name; string sTag = m_mediator.StringTbl.GetString(sType, "ClassNames"); SetDefaultVisibilityOfItems(false, sTag); m_fObjectConcorded = true; m_hvoMatch = cmo.Hvo; m_backupHvo = cmo.Owner == null ? 0 : cmo.Owner.Hvo; ITsTextProps ttpObj = tssObj.get_PropertiesAt(0); int nVar; int ws = ttpObj.GetIntPropValues((int)FwTextPropType.ktptWs, out nVar); m_fwtbItem.WritingSystemCode = (ws > 0) ? ws : m_cache.DefaultVernWs; int dyHeight = m_fwtbItem.PreferredHeight; m_fwtbItem.Height = dyHeight; m_fwtbItem.Tss = tssObj; int dxWidth = m_fwtbItem.PreferredWidth; m_fwtbItem.Width = dxWidth; LoadMatches(true); return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Determines whether or not the specified property name of the specified object /// should be displayed. /// </summary> /// ------------------------------------------------------------------------------------ public static bool IsPropertyDisplayed(ICmObject cmObj, string propName) { if (s_showCmObjProps || !IsCmObjectProperty(propName)) { FDOClass cls; if (s_FDOClassesByType.TryGetValue(cmObj.GetType(), out cls)) return cls.IsPropertyDisplayed(propName); } return false; }
/// <summary> /// This is the basic method needed for the view constructor. /// </summary> public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); switch (frag) { case VectorReferenceView.kfragTargetVector: // Check for an empty vector. if (m_cache.GetVectorSize(hvo, m_flid) == 0) { vwenv.set_IntProperty((int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)ColorUtil.ConvertColorToBGR(Color.Gray)); vwenv.set_IntProperty((int)FwTextPropType.ktptLeadingIndent, (int)FwTextPropVar.ktpvMilliPoint, 18000); vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvDefault, (int)TptEditable.ktptNotEditable); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); //vwenv.AddString(m_cache.MakeUserTss("Click to select -->")); vwenv.NoteDependency(new int[] { hvo }, new int[] { m_flid }, 1); } else { vwenv.OpenParagraph(); vwenv.AddObjVec(m_flid, this, frag); vwenv.CloseParagraph(); } break; case VectorReferenceView.kfragTargetObj: // Display one object from the vector. { ILgWritingSystemFactory wsf = m_cache.LanguageWritingSystemFactoryAccessor; vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvDefault, (int)TptEditable.ktptIsEditable); ITsString tss; ITsStrFactory tsf = TsStrFactoryClass.Create(); Debug.Assert(hvo != 0); #if USEBESTWS if (m_displayWs != null && m_displayWs.StartsWith("best")) { // The flid can be a variety of types, so deal with those. Debug.WriteLine("Using 'best ws': " + m_displayWs); int magicWsId = LangProject.GetMagicWsIdFromName(m_displayWs); int actualWS = m_cache.LangProject.ActualWs(magicWsId, hvo, m_flid); Debug.WriteLine("Actual ws: " + actualWS.ToString()); } else { #endif // Use reflection to get a prebuilt name if we can. Otherwise // settle for piecing together a string. Debug.Assert(m_cache != null); ICmObject obj = CmObject.CreateFromDBObject(m_cache, hvo); Debug.Assert(obj != null); System.Type type = obj.GetType(); System.Reflection.PropertyInfo pi = type.GetProperty("TsName", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); if (pi != null) { tss = (ITsString)pi.GetValue(obj, null); } else { if (m_displayNameProperty != null && m_displayNameProperty != string.Empty) { pi = type.GetProperty(m_displayNameProperty, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); } int ws = wsf.GetWsFromStr(obj.SortKeyWs); if (ws == 0) { ws = m_cache.DefaultAnalWs; } if (pi != null) { object s = pi.GetValue(obj, null); if (s is ITsString) { tss = (ITsString)s; } else { tss = tsf.MakeString((string)s, ws); } } else { tss = obj.ShortNameTSS; } #if USEBESTWS } #endif } vwenv.AddString(tss); } break; default: throw new ArgumentException( "Don't know what to do with the given frag.", "frag"); } }
protected void CreateMsaXmlElement(XmlNode node, XmlDocument doc, XmlNode morphNode, string sHvo) { XmlNode attr; // morphname contains the hvo of the msa attr = node.SelectSingleNode(sHvo); if (attr != null) { string sObjHvo = attr.Value; // Irregulary inflected forms can have a combination MSA hvo: the LexEntry hvo, a period, and an index to the LexEntryRef var indexOfPeriod = ParseFiler.IndexOfPeriodInMsaHvo(ref sObjHvo); ICmObject obj = m_cache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(Convert.ToInt32(sObjHvo)); switch (obj.GetType().Name) { default: throw new ApplicationException(String.Format("Invalid MSA type: {0}.", obj.GetType().Name)); case "MoStemMsa": IMoStemMsa stemMsa = obj as IMoStemMsa; CreateStemMsaXmlElement(doc, morphNode, stemMsa); break; case "MoInflAffMsa": IMoInflAffMsa inflMsa = obj as IMoInflAffMsa; CreateInflectionClasses(doc, morphNode); CreateInflMsaXmlElement(doc, morphNode, inflMsa); break; case "MoDerivAffMsa": IMoDerivAffMsa derivMsa = obj as IMoDerivAffMsa; CreateDerivMsaXmlElement(doc, morphNode, derivMsa); break; case "MoUnclassifiedAffixMsa": IMoUnclassifiedAffixMsa unclassMsa = obj as IMoUnclassifiedAffixMsa; CreateUnclassifedMsaXmlElement(doc, morphNode, unclassMsa); break; case "LexEntry": // is an irregularly inflected form // get the MoStemMsa of its variant var entry = obj as ILexEntry; if (entry.EntryRefsOS.Count > 0) { var index = ParseFiler.IndexOfLexEntryRef(attr.Value, indexOfPeriod); var lexEntryRef = entry.EntryRefsOS[index]; var sense = FDO.DomainServices.MorphServices.GetMainOrFirstSenseOfVariant(lexEntryRef); stemMsa = sense.MorphoSyntaxAnalysisRA as IMoStemMsa; CreateStemMsaXmlElement(doc, morphNode, stemMsa); } break; case "LexEntryInflType": // This is one of the null allomorphs we create when building the // input for the parser in order to still get the Word Grammar to have something in any // required slots in affix templates. CreateInflMsaForLexEntryInflType(doc, morphNode, obj as ILexEntryInflType); break; } } }
/// <summary> /// The <refObjVector> element is used when you want to expand the referenced /// objects as subparts of the same element in the output file. /// </summary> /// <param name="contentsStream"></param> /// <param name="currentObject"></param> /// <param name="node"></param> protected void DoReferenceObjVectorElement(TextWriter contentsStream, ICmObject currentObject, XmlNode node) { if (m_format != "sf") throw new ConfigurationException("<refObjVector> is supported only for standard format output."); string label = XmlUtils.GetOptionalAttributeValue(node, "itemLabel"); if (label == null) label = "subobject"; string field = XmlUtils.GetManditoryAttributeValue(node, "field"); string sVirtual = XmlUtils.GetOptionalAttributeValue(node, "virtual"); bool fVirtual = false; if (sVirtual != null) { sVirtual = sVirtual.ToLower(); if (sVirtual == "true" || sVirtual == "t" || sVirtual == "yes" || sVirtual == "y") fVirtual = true; } int flid = GetFieldId2(currentObject.ClassID, field, true); int[] hvos; if (flid <= 0) { if (fVirtual) { hvos = LoadVirtualField(currentObject, field); } else { throw new ConfigurationException("There is no field named '" + field + "' in " + currentObject.GetType().ToString() + ". Remember that fields are the actual CELLAR names, so they do not have FDO suffixes like OA or RS."); } } else { if (m_mapFlids.ContainsKey(flid)) flid = m_mapFlids[flid]; int chvo = m_cache.DomainDataByFlid.get_VecSize(currentObject.Hvo, flid); using (ArrayPtr arrayPtr = MarshalEx.ArrayToNative<int>(chvo)) { m_cache.DomainDataByFlid.VecProp(currentObject.Hvo, flid, chvo, out chvo, arrayPtr); hvos = MarshalEx.NativeToArray<int>(arrayPtr, chvo); } } string property = XmlUtils.GetOptionalAttributeValue(node, "itemProperty"); if (property == null) property = "ShortName"; string wsProp = XmlUtils.GetOptionalAttributeValue(node, "itemWsProp"); string sClassTag = XmlUtils.GetOptionalAttributeValue(node, "classtag"); string labelWs = ""; ILgWritingSystemFactory wsf = m_cache.WritingSystemFactory; foreach (int hvo in hvos) { var co = m_cmObjectRepository.GetObject(hvo); if (String.IsNullOrEmpty(label) || String.IsNullOrEmpty(property)) { contentsStream.WriteLine(); } else { object obj = GetProperty(co, property); if (obj == null) continue; string s = Icu.Normalize(obj.ToString(), m_eIcuNormalizationMode); string separator = ""; if (wsProp != null) { obj = GetProperty(co, wsProp); if (obj != null) { IWritingSystem ws = obj as IWritingSystem ?? m_wsManager.Get((string)obj); if (ws != null) labelWs = LabelString(ws); } } if (!String.IsNullOrEmpty(labelWs)) separator = "_"; string sTmp = String.Format("{4}\\{0}{1}{2} {3}", label, separator, labelWs, s, Environment.NewLine); contentsStream.Write(sTmp); } DumpObject(contentsStream, co, sClassTag); } }
public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); switch (frag) { case AtomicReferenceView.kFragAtomicRef: // Display a paragraph with a single item. int hvoProp = HvoOfObjectToDisplay(vwenv, hvo); if (hvoProp == 0) { vwenv.set_IntProperty((int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)ColorUtil.ConvertColorToBGR(Color.Gray)); vwenv.set_IntProperty((int)FwTextPropType.ktptLeadingIndent, (int)FwTextPropVar.ktpvMilliPoint, 18000); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); //vwenv.AddString(m_cache.MakeUserTss("Click to select -->")); vwenv.NoteDependency(new int[] { hvo }, new int[] { m_flid }, 1); } else { vwenv.OpenParagraph(); // vwenv.OpenMappedPara(); DisplayObjectProperty(vwenv, hvoProp); vwenv.CloseParagraph(); } break; case AtomicReferenceView.kFragObjName: // Display one reference. { ILgWritingSystemFactory wsf = m_cache.LanguageWritingSystemFactoryAccessor; vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvDefault, (int)TptEditable.ktptNotEditable); ITsString tss; ITsStrFactory tsf = TsStrFactoryClass.Create(); Debug.Assert(hvo != 0); // Use reflection to get a prebuilt name if we can. Otherwise // settle for piecing together a string. Debug.Assert(m_cache != null); ICmObject obj = CmObject.CreateFromDBObject(m_cache, hvo); Debug.Assert(obj != null); System.Type type = obj.GetType(); System.Reflection.PropertyInfo pi = type.GetProperty("TsName", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); if (pi != null) { tss = (ITsString)pi.GetValue(obj, null); } else { if (m_displayNameProperty != null && m_displayNameProperty != string.Empty) { pi = type.GetProperty(m_displayNameProperty, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); } int ws = wsf.GetWsFromStr(obj.SortKeyWs); if (ws == 0) { ws = m_cache.DefaultAnalWs; } if (pi != null) { object info = pi.GetValue(obj, null); // handle the object type if (info is String) { tss = tsf.MakeString((string)info, ws); } else if (info is MultiUnicodeAccessor) { MultiUnicodeAccessor accessor = info as MultiUnicodeAccessor; tss = accessor.GetAlternativeTss(ws); // try the requested one (or default analysis) if (tss == null || tss.Length == 0) { tss = accessor.BestAnalysisVernacularAlternative; // get something } } else if (info is ITsString) { tss = (ITsString)info; } else { tss = null; } } else { tss = obj.ShortNameTSS; // prefer this, which is hopefully smart about wss. if (tss == null || tss.Length == 0) { tss = tsf.MakeString(obj.ShortName, ws); } } } vwenv.AddString(tss); } break; default: throw new ArgumentException( "Don't know what to do with the given frag.", "frag"); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Merges object into this object. /// if fLoseNoStringData is false: /// For atomic properties, if this object has something in the property, the source /// property is ignored. For sequence properties, the objects in the source will be /// moved and appended to the properties in this object. Any references to the /// source object will be transferred to this object. The source object is deleted /// at the end of this method (objSrc.DeleteUnderlyingObject() call). /// String properties are copied from the source if the destination (this) has no value /// and the source has a value. /// /// if fLoseNoStringData is true, the above is modified as follows: /// 1. If a string property has a value in both source and destination, and the values /// are different, append the source onto the destination. /// 2. If an atomic object property has a value in both source and destination, /// recursively merge the value in the source with the value in the destination. /// </summary> /// <param name="objSrc">Object whose properties will be merged into this object's properties</param> /// <remarks> /// NB: The given object will be deleted in this method, so don't expect it to be valid, afterwards. /// </remarks> /// <param name="fLoseNoStringData"></param> /// ------------------------------------------------------------------------------------ public virtual void MergeObject(ICmObject objSrc, bool fLoseNoStringData) { Debug.Assert(m_cache != null); // We don't allow merging items of different classes. Debug.Assert(ClassID == objSrc.ClassID); if (ClassID != objSrc.ClassID) return; IFwMetaDataCache mdc = m_cache.MetaDataCacheAccessor; PropertyInfo[] myProperties = GetType().GetProperties(); PropertyInfo[] srcProperties = objSrc.GetType().GetProperties(); string fieldname; // Process all the fields in the source. foreach(uint flid in DbOps.GetFieldsInClassOfType(mdc, ClassID, FieldType.kgrfcptAll)) { /* These values will also be returned because they are for most of CmObject's flids. * I think it will do this for each superclass, so there could be some repeats on them. * * pvuFields->Push(101); // kflidCmObject_Guid * pvuFields->Push(102); // kflidCmObject_Class * pvuFields->Push(103); // kflidCmObject_Owner * pvuFields->Push(104); // kflidCmObject_OwnFlid * pvuFields->Push(105); // kflidCmObject_OwnOrd * //pvuFields->Push(106); // kflidCmObject_UpdStmp * //pvuFields->Push(107); // kflidCmObject_UpdDttm * */ if (flid < 1000) continue; // Do nothing for the CmObject flids. if (flid >= (int)SpecialTagValues.ktagMinVp) continue; // Do nothing for virtual properties. int nType = mdc.GetFieldType(flid); fieldname = mdc.GetFieldName(flid); //|| fieldname == "DateModified" //|| nType == (int)FieldType.kcptTime // This is handled by a separate connection, so it can time out, if another transaction is open. if (fieldname == "DateCreated" || nType == (int)FieldType.kcptImage // FDO does not support this one. || nType == (int)FieldType.kcptGenDate) // FDO does not support setter for gendate. continue; // Don't mess with this one. // Set suffixes on some of the types. switch (nType) { case (int)FieldType.kcptOwningAtom: // 23 { fieldname += "OA"; break; } case (int)FieldType.kcptReferenceAtom: // 24 { fieldname += "RA"; break; } case (int)FieldType.kcptOwningCollection: // 25 { fieldname += "OC"; break; } case (int)FieldType.kcptReferenceCollection: // 26 { fieldname += "RC"; break; } case (int)FieldType.kcptOwningSequence: // 27 { fieldname += "OS"; break; } case (int)FieldType.kcptReferenceSequence: // 28 { fieldname += "RS"; break; } } Object myCurrentValue = null; MethodInfo mySetMethod = null; Object srcCurrentValue = null; PropertyInfo pi = this.GetType().GetProperty(fieldname); if (pi != null) { myCurrentValue = pi.GetGetMethod().Invoke(this, null); mySetMethod = pi.GetSetMethod(); srcCurrentValue = objSrc.GetType().GetProperty(fieldname).GetGetMethod().Invoke(objSrc, null); } else { // We must have a custom field, and it needs special treatment. Debug.Assert(m_cache.GetIsCustomField(flid)); mySetMethod = null; string classname = mdc.GetOwnClsName(flid); string sView = classname + "_" + fieldname; switch (nType) { case (int)FieldType.kcptString: case (int)FieldType.kcptBigString: myCurrentValue = new TsStringAccessor(m_cache, m_hvo, (int)flid); srcCurrentValue = new TsStringAccessor(objSrc.Cache, objSrc.Hvo, (int)flid); break; case (int)FieldType.kcptMultiString: case (int)FieldType.kcptMultiBigString: myCurrentValue = new MultiStringAccessor(m_cache, m_hvo, (int)flid, sView); srcCurrentValue = new MultiStringAccessor(objSrc.Cache, objSrc.Hvo, (int)flid, sView); break; case (int)FieldType.kcptMultiUnicode: case (int)FieldType.kcptMultiBigUnicode: myCurrentValue = new MultiUnicodeAccessor(m_cache, m_hvo, (int)flid, sView); srcCurrentValue = new MultiUnicodeAccessor(objSrc.Cache, objSrc.Hvo, (int)flid, sView); break; } } if (srcCurrentValue == null) continue; // Nothing to merge. Debug.Assert(srcCurrentValue != null); /* * NOTE: Each of the cases (except the exception, which can't be tested) * is tested in the MergeObjectsTests class in the unit tests. * If any additions are made, or if some currently unused cases are enabled, * be sure to add them (or enable them) to that class, as well. */ switch (nType) { default: throw new ApplicationException("Unrecognized data type for merging: " + nType.ToString()); /* 0 -> 9 */ case (int)FieldType.kcptBoolean: // 1 { // Can't be null, so we have to live with default of 0 (false). // 0 gets replaced with source data, if 1 (true). bool myBool = (bool)myCurrentValue; bool srcBool = (bool)srcCurrentValue; if (!myBool && srcBool) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {srcCurrentValue}); } break; } // case (int)FieldType.kcptInteger: // 2 Fall through // Setter not implemented in FDO. case (int)FieldType.kcptGenDate: // 8 { // Can't be null, so we have to live with default of 0. // Zero gets replaced with source data, if greater than 0. int myInt = (int)myCurrentValue; int srcInt = (int)srcCurrentValue; if (myInt == 0 && srcInt > 0) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {srcCurrentValue}); } break; } case (int)FieldType.kcptTime: // 5 { // If it is DateCreated, we won't even be here, // since we will have already skipped it. bool resetTime = false; DateTime srcTime = DateTime.Now; // If it is DateModified, always set it to 'now'. if (fieldname == "DateModified") { // Already using 'Now'. resetTime = true; } else { // Otherwise, a later source will replace an older target. DateTime myTime = (DateTime)myCurrentValue; srcTime = (DateTime)srcCurrentValue; resetTime = (myTime < srcTime); if (myTime < srcTime) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {srcTime}); } } if (resetTime) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {srcTime}); } break; } case (int)FieldType.kcptGuid: // 6 { // May be null. Guid myGuidValue = (Guid)myCurrentValue; Guid srcGuidValue = (Guid)srcCurrentValue; if (myGuidValue == Guid.Empty && srcGuidValue != Guid.Empty) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {srcGuidValue}); mySetMethod.Invoke(objSrc, new object[] {Guid.Empty}); } break; } //case (int)FieldType.kcptImage: // 7 Fall through. case (int)FieldType.kcptBinary: // 8 { if (myCurrentValue == null) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {srcCurrentValue}); } break; } /* 13 -> 20 */ case (int)FieldType.kcptString: // 13 Fall through case (int)FieldType.kcptBigString: // 17 { if (MergeStringProp((int)flid, nType, objSrc, fLoseNoStringData, myCurrentValue, srcCurrentValue)) break; TsStringAccessor myTsa = myCurrentValue as TsStringAccessor; myTsa.MergeString(srcCurrentValue as TsStringAccessor, fLoseNoStringData); break; } case (int)FieldType.kcptMultiString: // 14 Fall through. case (int)FieldType.kcptMultiBigString: // 18 { if (MergeStringProp((int)flid, nType, objSrc, fLoseNoStringData, myCurrentValue, srcCurrentValue)) break; MultiStringAccessor myMsa = myCurrentValue as MultiStringAccessor; myMsa.MergeAlternatives(srcCurrentValue as MultiStringAccessor, fLoseNoStringData); break; } case (int)FieldType.kcptUnicode: // 15 Fall through. case (int)FieldType.kcptBigUnicode: // 19 { if (MergeStringProp((int)flid, nType, objSrc, fLoseNoStringData, myCurrentValue, srcCurrentValue)) break; string myUCurrent = myCurrentValue as string; string srcUValue = srcCurrentValue as string; if ((myUCurrent == null || myUCurrent == String.Empty) && srcUValue != String.Empty) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {srcUValue}); } else if (fLoseNoStringData && myUCurrent != null && myUCurrent != String.Empty && srcUValue != null && srcUValue != String.Empty && srcUValue != myUCurrent) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {myUCurrent + ' ' + srcUValue}); } break; } case (int)FieldType.kcptMultiUnicode: // 16 Fall through case (int)FieldType.kcptMultiBigUnicode: // 20 This one isn't actually used yet, but I hope it is the same as the small MultiUnicode { if (MergeStringProp((int)flid, nType, objSrc, fLoseNoStringData, myCurrentValue, srcCurrentValue)) break; MultiUnicodeAccessor myMua = myCurrentValue as MultiUnicodeAccessor; myMua.MergeAlternatives(srcCurrentValue as MultiUnicodeAccessor, fLoseNoStringData); break; } /* 23 -> 28 */ case (int)FieldType.kcptOwningAtom: case (int)FieldType.kcptReferenceAtom: // 24 { ICmObject srcObj = srcCurrentValue as ICmObject; ICmObject currentObj = myCurrentValue as ICmObject; if (myCurrentValue == null) { Debug.Assert(mySetMethod != null); mySetMethod.Invoke(this, new object[] {srcObj}); break; } else if (fLoseNoStringData && nType == (int)FieldType.kcptOwningAtom && srcObj != null && currentObj.GetType() == srcObj.GetType()) { // merge the child objects. currentObj.MergeObject(srcObj, true); } break; } case (int)FieldType.kcptOwningCollection: // 25 Fall through, since the collection class knows how to merge itself properly. case (int)FieldType.kcptReferenceCollection: // 26 { PropertyInfo piCol = FdoVector<ICmObject>.HvoArrayPropertyInfo(srcCurrentValue); MethodInfo myAddMethod = FdoCollection<ICmObject>.AddIntMethodInfo(myCurrentValue); foreach (int hvo in (int[])piCol.GetGetMethod().Invoke(srcCurrentValue, null)) { myAddMethod.Invoke(myCurrentValue, new object[] { hvo }); } break; } case (int)FieldType.kcptOwningSequence: // 27 Fall through, since the collection class knows how to merge itself properly. case (int)FieldType.kcptReferenceSequence: // 28 { PropertyInfo piCol = FdoVector<ICmObject>.HvoArrayPropertyInfo(srcCurrentValue); MethodInfo myAppendMethod = FdoSequence<ICmObject>.AppendIntMethodInfo(myCurrentValue); foreach (int hvo in (int[])piCol.GetGetMethod().Invoke(srcCurrentValue, null)) { myAppendMethod.Invoke(myCurrentValue, new object[] { hvo }); } break; } } } // Now move all incoming references. CmObject.ReplaceReferences(m_cache, objSrc, this); objSrc.DeleteUnderlyingObject(); }
private object GetObjectForTest(ICmObject currentObject, XmlNode node) { int hvo = 0; int flid = GetFlidAndHvo(currentObject, node, ref hvo); if (flid == 0 || hvo == 0) { string sField = XmlUtils.GetOptionalAttributeValue(node, "field"); if (String.IsNullOrEmpty(sField)) return null; // This is rather arbitrary...objects missing, what should each test do? try { Type type = currentObject.GetType(); PropertyInfo info = type.GetProperty(sField, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (info != null) { object result = info.GetValue(currentObject, null); return result; } } catch (Exception error) { throw new ApplicationException(string.Format("There was an error while trying to get the property {0}. One thing that has caused this in the past has been a database which was not migrated properly.", sField), error); } return null; // This is rather arbitrary...objects missing, what should each test do? } switch ((CellarPropertyType)m_mdc.GetFieldType(flid)) { case CellarPropertyType.OwningAtomic: case CellarPropertyType.ReferenceAtomic: int hvoT = currentObject.Cache.DomainDataByFlid.get_ObjectProp(hvo, flid); if (hvoT == 0) return null; else return String.Empty; // it's not null, which is all that matters for the test! default: return null; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the fields from meta data cache. /// </summary> /// ------------------------------------------------------------------------------------ private PropertyInfo[] GetFieldsFromMetaDataCache(ICmObject cmObj) { List<PropertyInfo> props = new List<PropertyInfo>(); if (cmObj != null) { int[] flids = m_mdc.GetFields(cmObj.ClassID, true, (int)CellarPropertyTypeFilter.All); BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; // Get only the fields for the object that are specified in the meta data cache. foreach (int flid in flids) { string fieldName = m_mdc.GetFieldName(flid); CellarPropertyType fieldType = (CellarPropertyType)m_mdc.GetFieldType(flid); string suffix; if (m_fldSuffix.TryGetValue(fieldType, out suffix)) fieldName += suffix; PropertyInfo pi = cmObj.GetType().GetProperty(fieldName, flags); if (pi != null) props.Add(pi); } } return (props.Count > 0 ? props.ToArray() : base.GetPropsForObj(cmObj)); }
private string GetStringValueForTest(ICmObject currentObject, XmlNode node) { int hvo = 0; int flid = GetFlidAndHvo(currentObject, node, ref hvo); if (flid == 0 || hvo == 0) { // Try for a property on the object. string sField = XmlUtils.GetOptionalAttributeValue(node, "field"); if (String.IsNullOrEmpty(sField)) return null; try { Type type = currentObject.GetType(); PropertyInfo info = type.GetProperty(sField, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (info != null) { object result = info.GetValue(currentObject, null); return result.ToString(); } } catch (Exception error) { throw new ApplicationException(string.Format("There was an error while trying to get the property {0}. One thing that has caused this in the past has been a database which was not migrated properly.", sField), error); } return null; // This is rather arbitrary...objects missing, what should each test do? } switch ((CellarPropertyType)m_mdc.GetFieldType(flid)) { case CellarPropertyType.Unicode: return currentObject.Cache.DomainDataByFlid.get_UnicodeProp(hvo, flid); case CellarPropertyType.String: return currentObject.Cache.DomainDataByFlid.get_StringProp(hvo, flid).Text; case CellarPropertyType.MultiUnicode: return currentObject.Cache.DomainDataByFlid.get_MultiStringAlt(hvo, flid, GetSingleWritingSystemDescriptor(node)).Text; case CellarPropertyType.MultiString: return currentObject.Cache.DomainDataByFlid.get_MultiStringAlt(hvo, flid, GetSingleWritingSystemDescriptor(node)).Text; default: return null; } }
protected void DumpObject(TextWriter contentsStream, ICmObject currentObject, string sClassTag) { string className = currentObject.ClassName; XmlNode classNode = null; if (sClassTag != null && sClassTag.Length > 0) { className = className + "-" + sClassTag; classNode = GetClassTemplateNode(className); } if (classNode == null) { classNode = FindClassTemplateNode(currentObject.GetType(), sClassTag); } if (classNode == null) { return; // would have thrown an exception if that's what the template wanted } if (m_filters != null) { foreach (IFilterStrategy filter in m_filters) { string explanation; if (!filter.DoInclude(currentObject, out explanation)) { if (explanation == null) explanation = "none"; using (var writer = XmlWriter.Create(contentsStream, new XmlWriterSettings { OmitXmlDeclaration = true, ConformanceLevel = ConformanceLevel.Fragment })) { writer.WriteComment(String.Format(" Object filtered out by filter {0}, reason: {1} ", filter.Label, explanation)); // would choke the parser later if there were reserved chars in there //contentsStream.Write("<!-- Object filtered out by filter " + filter.Label + ", reason: "+ explanation + " "); // contentsStream.Write(" -->"); } return; } } } DoChildren(/*null,*/ contentsStream, currentObject, classNode, null); }
protected object GetMethodResult(ICmObject target, string methodName, object[] args) { Type type = target.GetType(); MethodInfo mi = type.GetMethod(methodName); if (mi == null) throw new ConfigurationException ("There is no public method named '" + methodName + "."); object result = null; try { result = mi.Invoke(target, args); } catch (Exception error) { throw new ApplicationException (string.Format("There was an error while executing the method {0}.", methodName), error); } return result; }
protected object GetProperty(ICmObject target, string property) { if (target == null) { return null; } if (property == "Hvo") { return GetIdString(target.Hvo); } else if (property == "Guid") { return (target.Guid.ToString()); } else if (property == "Owner") { return target.Owner; } else if (property == "IndexInOwner") { return target.IndexInOwner.ToString(); } else if (IsCustomField(target, property)) { return GetCustomFieldValue(target, property); } Type type = target.GetType(); PropertyInfo info = type.GetProperty(property, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); bool fWantHvo = false; if (info == null && property.EndsWith(".Hvo")) { fWantHvo = true; string realprop = property.Substring(0, property.Length - 4); info = type.GetProperty(realprop, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); } if (info == null) { throw new ConfigurationException("There is no public property named '" + property + "' in " + type.ToString() + ". Remember, properties often end in a two-character suffix such as OA,OS,RA, or RS."); } object result = null; try { result = info.GetValue(target,null); if (fWantHvo) { int hvo = 0; if (result != null) hvo = ((ICmObject)result).Hvo; return hvo > 0 ? GetIdString(hvo) : "0"; } } catch (Exception error) { throw new ApplicationException (string.Format("There was an error while trying to get the property {0}. One thing that has caused this in the past has been a database which was not migrated properly.", property), error); } return result; }
/// <summary> /// The <refVector> element is used when you just want to make a list of /// references to other elements that will be in the output file. /// </summary> /// <param name="contentsStream"></param> /// <param name="currentObject"></param> /// <param name="node"></param> protected void DoReferenceVectorElement(TextWriter contentsStream, ICmObject currentObject, XmlNode node) { bool ordered = XmlUtils.GetBooleanAttributeValue(node, "ordered"); string label = XmlUtils.GetOptionalAttributeValue(node, "itemLabel"); if (label == null) label ="object"; string field = XmlUtils.GetManditoryAttributeValue(node, "field"); bool fXmlVirtual = XmlUtils.GetOptionalBooleanAttributeValue(node, "virtual", false); bool fWriteAsRelation = XmlUtils.GetOptionalBooleanAttributeValue(node, "writeAsRelation", false); //Debug.WriteLine ("<refVector field ="+field+">"); int flid = GetFieldId2(currentObject.ClassID, field, true); if (m_mapFlids.ContainsKey(flid)) flid = m_mapFlids[flid]; int[] hvos; if (flid <= 0) { if (fXmlVirtual) { hvos = LoadVirtualField(currentObject, field); } else { throw new ConfigurationException ("There is no field named '" + field + "' in "+currentObject.GetType().ToString()+". Remember that fields are the actual CELLAR names, so they do not have FDO suffixes like OA or RS."); } } else { int chvo = m_cache.DomainDataByFlid.get_VecSize(currentObject.Hvo, flid); using (ArrayPtr arrayPtr = MarshalEx.ArrayToNative<int>(chvo)) { m_cache.DomainDataByFlid.VecProp(currentObject.Hvo, flid, chvo, out chvo, arrayPtr); hvos = MarshalEx.NativeToArray<int>(arrayPtr, chvo); } } string property = XmlUtils.GetOptionalAttributeValue(node, "itemProperty"); if (property == null) property = "ShortName"; string wsProp = XmlUtils.GetOptionalAttributeValue(node, "itemWsProp"); if (m_format == "xml") { int index = 0; bool fInternalTraits = XmlUtils.GetOptionalBooleanAttributeValue(node, "internalTraits", false); string sFieldMemberOf = XmlUtils.GetOptionalAttributeValue(node, "fieldMemberOf"); string sFieldMemberOfTrait = XmlUtils.GetOptionalAttributeValue(node, "fieldMemberOfTrait"); int flidMemberOf = 0; if (!String.IsNullOrEmpty(sFieldMemberOf) && !String.IsNullOrEmpty(sFieldMemberOfTrait)) { flidMemberOf = GetFieldId2(currentObject.ClassID, sFieldMemberOf, true); } foreach (int hvo in hvos) { if (fWriteAsRelation) { string labelWs; string s; if (GetRefPropertyData(property, wsProp, hvo, out labelWs, out s)) { if (ordered && hvos.Length > 1) { contentsStream.Write("<relation type=\"{0}\" ref=\"{1}\" order=\"{2}\">", XmlUtils.MakeSafeXmlAttribute(label), XmlUtils.MakeSafeXmlAttribute(s), index); ++index; } else { contentsStream.Write("<relation type=\"{0}\" ref=\"{1}\">", XmlUtils.MakeSafeXmlAttribute(label), XmlUtils.MakeSafeXmlAttribute(s)); } if (fInternalTraits) { if (!ordered || index <= 1) { contentsStream.WriteLine(); DoChildren(contentsStream, currentObject, node, String.Empty); } if (flidMemberOf != 0) { int[] rghvoT = ((ISilDataAccessManaged)m_cache.DomainDataByFlid).VecProp(currentObject.Hvo, flidMemberOf); for (int i = 0; i < rghvoT.Length; ++i) { if (rghvoT[i] == hvo) { if (ordered && index > 1) contentsStream.WriteLine(); contentsStream.WriteLine("<trait name=\"{0}\" value=\"true\"/>", XmlUtils.MakeSafeXmlAttribute(sFieldMemberOfTrait)); break; } } } } contentsStream.WriteLine("</relation>"); } } else { if (ordered) { contentsStream.WriteLine("<{0} dst=\"{1}\" ord=\"{2}\"/>", label, GetIdString(hvo), index); ++index; } else { contentsStream.WriteLine("<{0} dst=\"{1}\"/>", label, GetIdString(hvo)); } } } if (fWriteAsRelation && fInternalTraits) return; } else if (m_format == "sf") { foreach (int hvo in hvos) { string labelWs; string s; if (GetRefPropertyData(property, wsProp, hvo, out labelWs, out s)) { string separator = String.Empty; if (!String.IsNullOrEmpty(labelWs)) separator = "_"; contentsStream.Write("{4}\\{0}{1}{2} {3}", label, separator, labelWs, s, Environment.NewLine); } } } Debug.Assert(node.ChildNodes.Count == 0, "Child nodes are not supported in refVector elements"); }
/// <summary> /// Use the MetaDataCache and reflection to store the XML data if at all possible. /// </summary> /// <returns><c>true</c> if data was stored, <c>false</c> otherwise.</returns> private bool StoreUnanticipatedDataIfPossible(ICmObject obj, XmlReader xrdrSub) { try { var metaDataCache = obj.Cache.MetaDataCache as IFwMetaDataCacheManaged; if (metaDataCache == null) return false; var flid = metaDataCache.GetFieldId(obj.GetType().Name, xrdrSub.Name, true); if (flid == 0) return false; var type = metaDataCache.GetFieldType(flid); // REVIEW: how do we handle custom fields? Do we need to worry about those in this context? var prop = obj.GetType().GetProperty(xrdrSub.Name); if (prop == null) return false; switch (type) { case (int)CellarPropertyType.MultiString: var ms = prop.GetValue(obj, null) as IMultiString; if (ms == null) return false; SetMultiStringFromXml(xrdrSub, ms); return true; case (int)CellarPropertyType.MultiUnicode: var mu = prop.GetValue(obj, null) as IMultiUnicode; if (mu == null) return false; SetMultiUnicodeFromXml(xrdrSub, mu); return true; default: // We don't know how to handle any other data types for now. The two above are the ones // that are relevant for translation anyway. return false; } } catch { return false; } }
/// <summary> /// Calls the sort method. /// </summary> /// <param name="cmo">The object.</param> /// <param name="sortedFromEnd">if set to <c>true</c> [sorted from end].</param> /// <returns></returns> private string CallSortMethod(ICmObject cmo, bool sortedFromEnd) { Type typeCmo = cmo.GetType(); try { MethodInfo mi = typeCmo.GetMethod(m_sMethodName); if (mi == null) return null; object obj; if (mi.GetParameters().Length == 2) { // Enhance JohnT: possibly we should seek to evaluate this every time, in case it is a magic WS like // "best vernacular". But interpreting those requires a flid, and we don't have one; indeed, the // method may retrieve information from several. So we may as well just accept that the fancy ones // won't work. if (m_ws == 0 && WritingSystemName != null) m_ws = LangProject.InterpretWsLabel(cmo.Cache, WritingSystemName, 0, 0, 0, null); obj = mi.Invoke(cmo, new object[] { sortedFromEnd, m_ws }); } else { obj = mi.Invoke(cmo, new object[] { sortedFromEnd }); } return (string)obj; } catch (Exception) { return null; } }
int MakeRealObject(ITsString tssTyped) { // Figure whether owning atomic or owning collection or owning sequence. Throw if none. IFwMetaDataCache mdc = m_fdoCache.MetaDataCacheAccessor; FieldType iType = m_fdoCache.GetFieldType(m_flidEmptyProp); iType &= FieldType.kcptVirtualMask; ISilDataAccess sdaReal = m_fdoCache.MainCacheAccessor; // Make a new object of the specified class in the specified property. int ord = 0; switch (iType) { default: throw new Exception("ghost string property must be owning object property"); case FieldType.kcptOwningAtom: ord = -2; break; case FieldType.kcptOwningCollection: ord = -1; break; case FieldType.kcptOwningSequence: // ord = 0 set above (inserting the first and only object at position 0). break; } string sClassRaw = mdc.GetClassName((uint)m_clidDst); string sClass = m_mediator.StringTbl.GetString(sClassRaw, "ClassNames"); string sUndo = String.Format(DetailControlsStrings.ksUndoCreate0, sClass); string sRedo = String.Format(DetailControlsStrings.ksRedoCreate0, sClass); sdaReal.BeginUndoTask(sUndo, sRedo); int hvoNewObj = sdaReal.MakeNewObject((int)m_clidDst, m_hvoObj, m_flidEmptyProp, ord); // Set its property m_flidStringProp to tssTyped. If it is multilingual, choose based on ghostWs. FieldType iTypeString = m_fdoCache.GetFieldType(m_flidStringProp); iTypeString &= FieldType.kcptVirtualMask; switch (iTypeString) { default: throw new Exception("ghost property must store strings!"); case FieldType.kcptMultiString: case FieldType.kcptMultiBigString: case FieldType.kcptMultiUnicode: case FieldType.kcptMultiBigUnicode: sdaReal.SetMultiStringAlt(hvoNewObj, m_flidStringProp, m_wsToCreate, tssTyped); break; case FieldType.kcptString: case FieldType.kcptBigString: sdaReal.SetString(hvoNewObj, m_flidStringProp, tssTyped); break; } string ghostInitMethod = XmlUtils.GetOptionalAttributeValue(m_nodeObjProp, "ghostInitMethod"); if (ghostInitMethod != null) { ICmObject obj = CmObject.CreateFromDBObject(m_fdoCache, hvoNewObj); Type objType = obj.GetType(); System.Reflection.MethodInfo mi = objType.GetMethod(ghostInitMethod); mi.Invoke(obj, null); } // Issue PropChanged for the addition of the new object. (could destroy this). sdaReal.PropChanged(null, (int)PropChangeType.kpctNotifyAll, m_hvoObj, m_flidEmptyProp, 0, 1, 0); sdaReal.EndUndoTask(); return(hvoNewObj); }
protected object GetProperty(ICmObject target, string property) { if (target == null) return null; var fWantHvo = false; var type = target.GetType(); var info = type.GetProperty(property, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (info == null && property.EndsWith(".Hvo")) { fWantHvo = true; var realprop = property.Substring(0, property.Length - 4); info = type.GetProperty(realprop, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); } if (info == null) throw new ConfigurationException("There is no public property named '" + property + "' in " + type + ". Remember, properties often end in a two-character suffix such as OA,OS,RA, or RS."); object result; try { result = info.GetValue(target, null); if (fWantHvo) { var hvo = 0; if (result != null) hvo = ((ICmObject)result).Hvo; return hvo > 0 ? hvo.ToString() : "0"; } } catch (Exception error) { throw new ApplicationException(String.Format("There was an error while trying to get the property {0}. One thing that has caused this in the past has been a database which was not migrated properly.", property), error); } return result; }