public void Add(IEffectBuilder effect, IFormBuilder form, IStatBuilder stat, IValueBuilder value) { var builder = _modifierBuilder .WithForm(form) .WithStat(effect.AddStat(stat)) .WithValue(value); _data.Add(builder.Build()); }
public NotchianSegmentBuilder(IValueBuilder valueParser) { valueBuilder = valueParser; symbolicLabels = new Stack<string>(); relativeLabels = new Queue<Label>(); instructions = new Queue<IInstruction>(); segments = new List<ISegment>(); }
public static double Convert(IValueBuilder value) { if (value is ValueBuilder b) { // Easiest way to get the underlying value back. value = b.Resolve(null); } return(((ValueBuilderStub)value).Value); }
private static IEnumerable <Modifier> CreateModifier( IStatBuilder statBuilder, IFormBuilder formBuilder, IValueBuilder valueBuilder) { var statBuilderResults = statBuilder.Build(default(BuildParameters).With(new ModifierSource.Global())); var(form, formValueConverter) = formBuilder.Build(); foreach (var(stats, source, statValueConverter) in statBuilderResults) { var value = formValueConverter(statValueConverter(valueBuilder)).Build(default);
private static IValue Build( BuildParameters parameters, IValueBuilder operand, Func <NodeValue?, bool> calculate, Func <IValue, string> identity) { var builtOperand = operand.Build(parameters); return(new ConditionalValue(c => calculate(builtOperand.Calculate(c)), identity(builtOperand))); }
/// <summary> "@toLowerCase( Source )" /// /// Converts the source string to lowercase /// </summary> public static string ToLowerCase(IValueBuilder vb, string source) { try { return(source.Trim().ToLower()); } catch { return(source); } }
/// <summary> /// Adds a matcher with a form, value and stats. /// </summary> public void Add( [RegexPattern] string regex, IFormBuilder form, IValueBuilder value, params IStatBuilder[] stats) { var builder = ModifierBuilder .WithForm(form) .WithStats(stats) .WithValue(value); Add(regex, builder); }
/// <summary> /// Adds a substituting matcher with a form, value and stat. /// </summary> public void Add([RegexPattern] string regex, IFormBuilder form, IValueBuilder value, IStatBuilder stat, string substitution) { var builder = ModifierBuilder .WithForm(form) .WithValue(value) .WithStat(stat); Add(regex, builder, substitution); }
private static IValue Build( BuildParameters parameters, IValueBuilder left, IValueBuilder right, Func <NodeValue?, NodeValue?, bool> calculate, Func <IValue, IValue, string> identity) { var l = left.Build(parameters); var r = right.Build(parameters); return(new ConditionalValue(c => calculate(l.Calculate(c), r.Calculate(c)), identity(l, r))); }
public IConditionalValueBuilder Then(IValueBuilder value) { IConditionalValueBuilder Resolve(ResolveContext context) { return(new ConditionalValueBuilder( $"{this.Resolve(context)} else if ({value.Resolve(context)})", (current, _) => current)); } return(new ConditionalValueBuilder($"{this} else if ({value})", (_, context) => Resolve(context))); }
public TestObjectFactory(IValueBuilder[] builders, List<Type> modelTypes) { CollectionCount = 10; MaximumHierarchyDepth = 2; ModelTypes = modelTypes; this.builders = builders; foreach (var builder in builders) builder.Factory = this; }
/// <summary> /// Strips Postal codes to report only the first 5 digits /// </summary> /// <returns></returns> public static String CleanupPostalCode(IValueBuilder vb, string zipcode) { //we only want to report 4 digit zip codes string formatted = zipcode; int index = zipcode.IndexOf("-"); if (index != -1) { formatted = zipcode.Substring(0, index); } return(formatted); }
public void Add(IFormBuilder form, IStatBuilder stat, IValueBuilder value, IConditionBuilder?condition = null) { var builder = _modifierBuilder .WithForm(form) .WithStat(stat) .WithValue(value); if (condition != null) { builder = builder.WithCondition(condition); } _data.Add(builder.Build()); }
public void IfBuildsToCorrectValue(int trueBranch) { var sut = CreateSut(); IValueBuilder valueBuilder = sut .If(ConstantConditionBuilder.Create(trueBranch == 0)) .Then(0) .ElseIf(ConstantConditionBuilder.Create(trueBranch == 1)) .Then(new ValueBuilderImpl(1)) .Else(2); var actual = valueBuilder.Build().Calculate(null!); Assert.AreEqual(new NodeValue(trueBranch), actual); }
private IValue Build(Skill skill, IValueBuilder valueBuilder, Entity modifierSourceEntity) { var gem = skill.Gem; if (gem is null) { return(new Constant(0)); } var displayName = GetSkillDefinition(gem.SkillId).DisplayName; var gemModifierSource = new ModifierSource.Local.Gem(gem, displayName); var buildParameters = new BuildParameters(new ModifierSource.Global(gemModifierSource), modifierSourceEntity, default); return(valueBuilder.Build(buildParameters)); }
/// <summary> /// Adds a matcher with a form, value, stat and optionally a condition. /// </summary> public void Add([RegexPattern] string regex, IFormBuilder form, IValueBuilder value, IStatBuilder stat, IConditionBuilder condition = null) { var builder = ModifierBuilder .WithForm(form) .WithStat(stat) .WithValue(value); if (condition != null) { builder = builder.WithCondition(condition); } Add(regex, builder); }
public IModifierBuilder WithValue(IValueBuilder value) { if (ReferenceEquals(value, null)) { throw new ArgumentNullException(nameof(value)); } if (Values != null) { throw new InvalidOperationException(); } var ret = (ModifierBuilderStub)MemberwiseClone(); ret.Values = new[] { value }; return(ret); }
private void Add( IStatBuilder stat, Form form, IValueBuilder value, IConditionBuilder?condition, ModifierSource modifierSource) { var builder = _modifierBuilder .WithStat(stat) .WithForm(_builderFactories.FormBuilders.From(form)) .WithValue(value); if (condition != null) { builder = builder.WithCondition(condition); } var intermediateModifier = builder.Build(); _modifiers.AddRange(intermediateModifier.Build(modifierSource, _modifierSourceEntity)); }
private IValue BuildInPastXSecondsValue(BuildParameters parameters, IValueBuilder seconds) { var builtEntity = BuildEntity(parameters, Entity); var recentOccurrencesStat = BuildRecentOccurrencesStat(parameters, builtEntity); var lastOccurenceStat = BuildLastOccurrenceStat(parameters, builtEntity); var secondsValue = seconds.Build(parameters); return(new ConditionalValue(Calculate, $"({RecentlySeconds} <= {secondsValue} && {recentOccurrencesStat} > 0) " + $"|| {lastOccurenceStat} <= {secondsValue}")); bool Calculate(IValueCalculationContext context) { NodeValue?threshold = secondsValue.Calculate(context); if (RecentlySeconds <= threshold && context.GetValue(recentOccurrencesStat) > 0) { return(true); } return(context.GetValue(lastOccurenceStat) <= threshold); } }
/// <summary> "@toMixedCase( Source )" /// /// Converts the source string to mixed case /// </summary> public static string toMixedCase(IValueBuilder vb, string source) { try { StringBuilder b = new StringBuilder(); string _source = source.Trim(); for (int i = 0; i < _source.Length; i++) { if (i == 0 || _source[i - 1] == ' ') { b.Append(Char.ToUpper(_source[i])); } else { b.Append(Char.ToLower(_source[i])); } } return(b.ToString()); } catch { return(source); } }
internal void MapOutbound( SifXPathContext context, IFieldAdaptor adaptor, SifElement dataObject, ICollection<FieldMapping> fields, IValueBuilder valueBuilder, SifVersion version) { #if PROFILED if( BuildOptions.PROFILED ){ ProfilerUtils.profileStart( String.valueOf( com.OpenADK.sifprofiler.api.OIDs.ADK_OUTBOUND_TRANSFORMATIONS ), dataObject.getElementDef(), null ); } #endif SifFormatter textFormatter = Adk.TextFormatter; FieldMapping lastRule = null; try { foreach (FieldMapping fm in fields) { lastRule = fm; String fieldName = fm.Alias; if (fieldName == null) { fieldName = fm.FieldName; } if (fieldName == null || fieldName.Length == 0) { throw new AdkMappingException( "Mapping rule for " + dataObject.ElementDef.Name + "[" + fm.FieldName + "] must specify a field name", null); } if (adaptor.HasField(fieldName) || fm.HasDefaultValue) { // // For outbound mapping operations, only process // XPathRules. All other rule types, like OtherIdRule, // are only intended to be used for inbound mappings. // if (fm.fRule is XPathRule) { XPathRule rule = (XPathRule) fm.fRule; // Lookup or create the element/attribute referenced by the rule String ruledef = rule.XPath; if (ruledef == null || ruledef.Trim().Length == 0) { throw new AdkMappingException( "Mapping rule for " + dataObject.ElementDef.Name + "[\"" + fieldName + "\"] must specify a path to an element or attribute", null); } // TT 199 If the FieldMapping has an "ifnull" value of "suppress", // don't render a result // Determine if this element should be created before attempting to create it // If the value resolves to null and the IFNULL_SUPPRESS flag is set, the element // should not be created. That's why we have to look up the ElementDef first TypeConverter typeConverter = null; IElementDef def = rule.LookupTargetDef(dataObject.ElementDef); if (def != null) { typeConverter = def.TypeConverter; } if (typeConverter == null) { typeConverter = SifTypeConverters.STRING; // TODO: Perhaps the following exception should be thrown when // in STRICT mode // throw new ADKMappingException( "Element {" + def.name() + // "} from rule \"" + ruledef + "\" does not have a data type definition.", null ); } SifSimpleType mappedValue; mappedValue = adaptor.GetSifValue(fieldName, typeConverter, fm); // Perform a valueset translation, if applicable if (mappedValue != null && mappedValue is SifString && fm.ValueSetID != null) { String textValue = mappedValue.ToString(); // Perform automatic ValueSet translation ValueSet vs = GetValueSet(fm.ValueSetID, true); if (vs != null) { // TT 199. Perform a more detailed valueset translation. // If there is a default value for this field, use it if there is // no match found in the value set textValue = vs.Translate(textValue, fm.DefaultValue); } mappedValue = new SifString(textValue); } bool usedDefault = false; if (mappedValue == null || mappedValue.RawValue == null) { // If the FieldMapping has a Default value, use that, unless // it is explicitly suppressed if (fm.NullBehavior != MappingBehavior.IfNullSuppress && fm.HasDefaultValue) { mappedValue = fm.GetDefaultValue(typeConverter, textFormatter); usedDefault = true; } else { continue; } } if (!usedDefault) { String valueExpression = rule.ValueExpression; if (valueExpression != null) { // This XPath rule has a value assignment expression at the end of it String value = valueBuilder.Evaluate(valueExpression); mappedValue = typeConverter.Parse(textFormatter, value); } } // If we have a null value to assign at this point, move on to the next rule if (mappedValue == null || mappedValue.RawValue == null) { continue; } // At this point, mappedValue should not be null. We are committeed // to building out the path and setting the value. INodePointer pointer = rule.CreatePath(context, version); // If the element/attribute does not have a value, assign one. // If it does have a value, it was already assigned by the XPath // rule in the lookupByXPath method above and should not be // changed. // if (pointer != null) { Element pointedElement = (Element) pointer.Value; SifSimpleType elementValue = pointedElement.SifValue; if (elementValue == null || elementValue.RawValue == null) { if (mappedValue is SifString) { // Now that we have the actual element, we may need to create convert the // data if we were unable to resolve the TypeConverter above. This only happens // in cases involving surrogates where the rule.lookupTargetDef( dataObject.getElementDef() ); // fails to find the target ElementDef TypeConverter converter = pointedElement.ElementDef.TypeConverter; if (converter != null && converter.DataType != mappedValue.DataType) { mappedValue = converter.Parse(textFormatter, mappedValue.ToString()); } } // This check for null should really not be necessary, // however keepingit in for now if (mappedValue != null) { pointedElement.SifValue = mappedValue; } } } } } } } catch (Exception e) { if (lastRule != null) { throw new AdkMappingException( "Unable to evaluate field rule: " + lastRule.fRule + " : " + e.Message, null, e); } throw new AdkMappingException(e.ToString(), null, e); } #if PROFILED finally { if( BuildOptions.PROFILED ) ProfilerUtils.profileStop(); } #endif }
public RequiredValueBuilder(IValueBuilder underlyingBuilder) { this.underlyingBuilder = underlyingBuilder; }
public IModifierBuilder WithValue(IValueBuilder value) { return(WithSingle(value, (e, v) => e.WithValue(v), e => e.Value, "Value")); }
public static IConditionBuilder Create( IValueBuilder left, IValueBuilder right, Func <NodeValue?, NodeValue?, bool> calculate, Func <IValue, IValue, string> identity) => new ValueConditionBuilder <IValueBuilder, IValueBuilder>( (p, o1, o2) => Build(p, o1, o2, calculate, identity), left, right);
public static IConditionBuilder Create( IValueBuilder operand, Func <NodeValue?, bool> calculate, Func <IValue, string> identity) => new ValueConditionBuilder <IValueBuilder>((p, o) => Build(p, o, calculate, identity), operand);
public IActionBuilder EveryXSeconds(IValueBuilder interval) { var stringBuilder = CoreBuilder.Create(interval, BuildEveryXSecondsIdentity); return(new ActionBuilder(_statFactory, stringBuilder, _entity)); }
public IActionBuilder SpendMana(IValueBuilder amount) { var stringBuilder = CoreBuilder.Create(amount, BuildSpendManaIdentity); return(new ActionBuilder(_statFactory, stringBuilder, _entity)); }
/// <summary> /// Creates a child element and sets the text value /// </summary> /// <param name="relativeTo">The parent SIFElement to add the new element to</param> /// <param name="tag">The tag name of the element</param> /// <param name="valueBuilder">The ValueBuilder instance to use to evaluate macros</param> /// <param name="version">The version of SIF for which this mapping operation is being evaluated</param> /// <param name="textFormatter">The SIFFormatter instance used to parse strings into strongly-typed data values. /// For many uses of this API, this formatter is equivalent to Adk.TextFormatter</param> /// <param name="pathFormatter">The SIFFormatter instance used for setting child SIFElements on their parents. /// This formatter may be different than the text formatter. The text formatter is, for /// compatibility's sake defaulted to SIF 1.x. However, the path formatter must be /// correct for the mappings path being evaluated.</param> /// <returns></returns> private SifElement _createChild( SifElement relativeTo, String tag, IValueBuilder valueBuilder, SifVersion version, SifFormatter textFormatter, SifFormatter pathFormatter) { string _tag = tag; string assignValue = null; int eq = tag.IndexOf('='); if (eq != -1) { _tag = tag.Substring(0, (eq) - (0)); string str = tag.Substring(eq + 1); assignValue = valueBuilder == null ? str : valueBuilder.Evaluate(str); } // Lookup the IElementDef IElementDef def = Adk.Dtd.LookupElementDef(relativeTo.ElementDef, _tag); if (def == null) { def = Adk.Dtd.LookupElementDef(_tag); } if (def == null) { throw new AdkSchemaException(_tag + " is not a recognized element or attribute of " + relativeTo.Tag); } try { TypeConverter defConverter = def.TypeConverter; if (defConverter == null) { defConverter = SifTypeConverters.STRING; } if (def.Field) { SimpleField field = defConverter.ParseField(relativeTo, def, textFormatter, assignValue); relativeTo.SetField(field); } else { // Create element instance SifElement ele = (SifElement)ClassFactory.CreateInstance(def.FQClassName); ele.ElementDef = def; pathFormatter.AddChild(relativeTo, ele, version); if (assignValue != null) { // TODO: THis needs to be done using the type converter ele.TextValue = assignValue; } return ele; } } catch (TypeLoadException tle) { throw new SystemException( "The " + def.Package + " Sdo module is not loaded (ensure the Adk is initialized to load this module)", tle); } catch (Exception thr) { throw new SystemException( "Failed to create an instance of the " + def.ClassName + " class from the " + def.Package + " Sdo module: ", thr); } return null; }
/// <summary> /// Create all elements and attributes referenced by the XPath-like query string. /// </summary> /// <param name="relativeTo">The element that is the starting point of the path</param> /// <param name="query">The xPath query to build out</param> /// <param name="valueBuilder">The class to use for </param> /// <returns></returns> public Element CreateElementOrAttributeFromXPath( SifElement relativeTo, String query, IValueBuilder valueBuilder) { SifVersion version = Adk.SifVersion; SifFormatter pathFormatter = GetFormatter(version); SifFormatter textFormatter = Adk.TextFormatter; return CreateElementOrAttributeFromXPath( relativeTo, query, valueBuilder, version, textFormatter, pathFormatter); }
public CodetableProvider(IValueBuilder valueBuilder) { ArgumentValidator.AssertNotNull(valueBuilder, nameof(valueBuilder)); _valueBuilder = valueBuilder; this.Codetables = new CodetableControllerInfo[] { }; }
/// <summary>Sets an element or attribute value identified by an XPath-like query string.</summary> /// <remarks> /// NOTE: This method makes calls to SIFXPathContext. If multiple calls to /// <c>setElementOrAttribute</c> are being done, it is much more efficient to create /// a new <c>SifXPathContext</c> by calling <c>SifXPathContext.NewInstance(sdo)</c> and then /// calling <c>.SetElementorAttributeon</c> on that SifXPathContext instance /// </remarks> /// <param name="xpath">An XPath-like query string that identifies the element or /// attribute to set. The string must reference elements and attributes /// by their <i>version-independent</i> names. /// </param> /// <param name="valu">The value to assign to the element or attribute if the /// query string does not set a value; may be null /// </param> /// <param name="valueBuilder">a ValueBuilder implementation that evaluates /// expressions in XPath-like query strings using name/value pairs in /// the <i>variables</i> map /// </param> public virtual void SetElementOrAttribute( string xpath, string valu, IValueBuilder valueBuilder ) { valu = valueBuilder == null ? valu : valueBuilder.Evaluate( valu ); SetElementOrAttribute( xpath, valu ); }
public BuildingSerializer(SerializerWithWireType serializer, IValueBuilder builder) { this.serializer = serializer; this.builder = builder; }
public IFlagStatBuilder ApplyModifiersTo(IStatBuilder stat, IValueBuilder percentOfTheirValue) => CreateFlagStat(This, stat, percentOfTheirValue, (o1, o2, o3) => $"Modifiers to {o1} apply to {o2} at {o3}% of their value");
/** * Sets the ValueBuilder instance to use for mapping operations. * @param functions A class implementing the ValueBuilder interface */ public void SetValueBuilder(IValueBuilder functions) { fValueBuilder = functions; }
public IBuffBuilder ForXSeconds(IValueBuilder seconds) => (IBuffBuilder)Create <IEffectBuilder, IStatBuilder, IValueBuilder>( (s, r) => new BuffBuilderStub(s, r), This, seconds, (o1, o2) => $"{o1} as Buff for {o2} seconds");
/// <summary> Find an SifElement given an XPath-like query string.</summary> /// <remarks> /// <para> /// Query strings can only take one of these forms: /// </para> /// <list type="bullet"> /// <item><term><c>@Attr</c></term></item> /// <item><term><c>Element</c></term></item> /// <item><term><c>Element/@Attr</c></term></item> /// <item><term><c>Element/Element/.../@Attr</c></term></item> /// <item><term><c>Element[@Attr='value1']</c></term></item> /// <item><term><c>Element[@Attr1='value1',@Attr2='value2',...]/Element/...</c></term></item> /// </list> /// /// <para> /// When the <i>create</i> parameter is true, the method will ensure that /// the elements and attributes specified in the query string are created in /// the SifDataObject. All values are evaluated by the ValueBuilder implementation /// passed to this method. In addition, the query string may end with a value /// expression in the form "<c>Element[@Attribute='val']=<b><i>expression</i></b></c>", /// where <i>expression</i> is evaluated by the <c>ValueBuilder</c>. /// Refer to the <c>DefaultValueBuilder</c> class for a description of /// how value expressions are evaluated by in XPath query strings by default. /// </para> /// <para> /// Note that when <i>create</i> is true, this method will attempt to create /// a new element when a set of attributes is specified and an element does /// not already exist with those same attribute settings. This is not always /// desirable, however. For example, if you call this method in succession /// with the following XPath query strings, the result will be a single /// <c>OtherId[@Type='ZZ']</c> element with a value of "$(School)". /// This is because each call will match the <c>OtherId[@Type='ZZ']</c> /// element created by the first call, and will replace its value instead of /// creating an new instance of the <c>OtherId</c> element: /// </para> /// /// <para> /// <code> /// OtherId[@Type='ZZ']=GRADE:$(Grade) /// OtherId[@Type='ZZ']=HOMEROOM:$(HomeRoom) /// OtherId[@Type='ZZ']=SCHOOL:$(School) /// </code> /// </para> /// /// <para> /// Produces: /// </para> /// <para> /// <c><OtherId Type='ZZ'>SCHOOL:$(School)</OtherId></c> /// </para> /// <para> /// To instruct the function to always create a new instance of an element /// even when a matching element is found, append the attribute list with a /// plus sign. The plus sign must come immediately before the closing right /// backet regardless of how many attributes are specified in the attribute /// list: /// </para> /// <para> /// <code> /// OtherId[@Type='ZZ'+]=GRADE:$(Grade) /// OtherId[@Type='ZZ'+]=HOMEROOM:$(HomeRoom) /// OtherId[@Type='ZZ'+]=SCHOOL:$(School) /// </code> /// </para> /// <para> /// Produces: /// </para> /// <para> /// <code> /// <OtherId Type='ZZ'>GRADE:$(Grade)</OtherId> /// <OtherId Type='ZZ'>HOMEROOM:$(HomeRoom)</OtherId> /// <OtherId Type='ZZ'>SCHOOL:$(School)</OtherId> /// </code> /// </para> /// </remarks> /// <param name="relativeTo">A SifDataObject to which the query is relative to.</param> /// <param name="query">An XPath-like query string as described above.</param> /// <returns> The Element satisfying the query, or <c>null</c> if no /// match was found (unless the <i>create</i> parameter is true). If the /// query resolves to an attribute, a SimpleField object is returned. If /// it resolves to an element, a SifElement object is returned. In both /// cases the caller can obtain the text value of the attribute or /// element by calling its <c>TextValue</c> property. /// </returns> /// <param name="valueBuilder"></param> public Element LookupByXPath(SifDataObject relativeTo, string query, IValueBuilder valueBuilder) { int i = query.IndexOf('/'); Element result = _xpath(relativeTo, query.Substring(0, (i == -1 ? query.Length : i) - (0)), i == -1 ? null : query.Substring(i + 1)); return result; }
private static string BuildSpendManaIdentity(BuildParameters parameters, IValueBuilder builder) => $"Spend{builder.Build(parameters).Calculate(new ThrowingContext())}Mana";
/// <summary> /// Create all elements and attributes referenced by the XPath-like query string. /// </summary> /// <param name="relativeTo">The element that is the starting point of the path</param> /// <param name="query">The xPath query to build out</param> /// <param name="valueBuilder">The class to use for</param> /// <param name="version">The version of SIF for which this mapping operation is being evaluated</param> /// <param name="textFormatter">The SIFFormatter instance used to parse strings into strongly-typed data values. /// For many uses of this API, this formatter is equivalent to Adk.TextFormatter</param> /// <param name="pathFormatter">The SIFFormatter instance used for setting child SIFElements on their parents. /// This formatter may be different than the text formatter. The text formatter is, for /// compatibility's sake defaulted to SIF 1.x. However, the path formatter must be /// correct for the mappings path being evaluated. </param> /// <returns></returns> public Element CreateElementOrAttributeFromXPath( SifElement relativeTo, String query, IValueBuilder valueBuilder, SifVersion version, SifFormatter textFormatter, SifFormatter pathFormatter) { int i = query.IndexOf('/'); String currentSegment; String nextSegment = null; if (i == -1) { currentSegment = query; } else { currentSegment = query.Substring(0, i); nextSegment = query.Substring(i + 1); } Element result = _xpathBuild(relativeTo, new StringBuilder(), currentSegment, nextSegment, null, valueBuilder, version, textFormatter, pathFormatter); return result; }
private static string BuildEveryXSecondsIdentity(BuildParameters parameters, IValueBuilder builder) => $"Every{builder.Build(parameters).Calculate(new ThrowingContext())}Seconds";
/// <summary> Recursively builds elements and attributes relative to a SifElement.</summary> /// <param name="relativeTo">The SifElement this iteration is relative to. For the /// first call to this method, the <i>relativeTo</i> parameter is usually /// a SifDataObject such as StudentPersonal to which the XPath query /// string is relative. With each subsequent call it is the SifElement /// or SimpleField that was previously processed.</param> /// <param name="path">A running path of the segments processed thus far; an empty /// StringBuffer should be passed to this parameter the first time the /// method is called </param> /// <param name="curSegment">The current segment of the path that is being processed. /// For the first call to this method, the <i>curSegment</i> should be /// the portion of the XPath query string up to the first forward slash, /// exclusive.</param> /// <param name="nextSegment">The remaining portion of the path to be processed. /// For the first call to this method, the <i>nextSegment</i> should be /// the portion of the XPath query string following the first forward /// slash.</param> /// <param name="prevAttributes">An optional array of attribute values that were /// used to construct an Element in the processing of the last segment. /// The array is comprised of attribute name and value pairs such that /// element N is an attribute name and N+1 is its value. For the first /// call to this method, the array should be null. For subsequent calls, /// it should be null unless an Element was constructed from attribute /// values.</param> /// <param name="version">The version of SIF for which this mapping operation is being evaluated</param> /// <param name="textFormatter">The SIFFormatter instance used to parse strings into strongly-typed data values. /// For many uses of this API, this formatter is equivalent to ADK.TextFormatter</param> /// <param name="pathFormatter">The SIFFormatter instance used for setting child SIFElements on their parents. /// This formatter may be different than the text formatter. The text formatter is, for /// compatibility's sake defaulted to SIF 1.x. However, the path formatter must be /// correct for the mappings path being evaluated.</param> /// <param name="valueBuilder"></param> /// <returns> The Element satisfying the query, or <c>null</c> if no /// match was found (unless the <i>create</i> parameter is true). If the /// query resolves to an attribute, a SimpleField object is returned. If /// it resolves to an element, a SifElement object is returned. In both /// cases the caller can obtain the text value of the attribute or /// element by calling its <c>TextValue</c> Property. /// </returns> private Element _xpathBuild( SifElement relativeTo, StringBuilder path, string curSegment, string nextSegment, string[] prevAttributes, IValueBuilder valueBuilder, SifVersion version, SifFormatter textFormatter, SifFormatter pathFormatter) { string[] _prevAttributes = null; SifElement nextEle = null; int asgnEq = curSegment.LastIndexOf('='); int attr = curSegment.LastIndexOf('@', asgnEq == -1 ? curSegment.Length - 1 : asgnEq - 1); int bracket = curSegment.IndexOf('['); if (bracket != -1) { if (attr == -1) { throw new AdkSchemaException("Invalid query: \"" + curSegment + "\" must be in the form [@Attr='value1','value2',...]"); } string subEleTag = curSegment.Substring(0, (bracket) - (0)); int lastBracket = curSegment.LastIndexOf(']'); string[] attrList = curSegment.Substring(bracket + 1, (lastBracket) - (bracket + 1)).Split(','); _prevAttributes = new string[attrList.Length * 2]; int _prevI = 0; for (int a = 0; a < attrList.Length; a++) { string _curSegment = attrList[a]; // Determine the value of the attribute int eq = _curSegment.IndexOf("="); string val = _curSegment.Substring(eq + 1); string v = null; if (val[0] == '\'') { int end = val.IndexOf('\'', 1); if (end != -1) { v = valueBuilder == null ? val.Substring(1, (end) - (1)) : valueBuilder.Evaluate(val.Substring(1, (end) - (1))); } } if (v == null) { throw new AdkSchemaException("Attribute value (" + val + ") must be in the form @Attribute='value'"); } string attrName = _curSegment.Substring(1, (eq) - (1)); _prevAttributes[_prevI++] = attrName; _prevAttributes[_prevI++] = v; if (nextEle == null) { // // Look at all of the peer elements to determine if any have the // attribute value set. If so, return it; otherwise create a new // instance of the element with the attribute set. For example, if // curSegment is "Address[@Type='M']", we must look at all of the // Address children of relativeTo in order to determine if any // currently exist with a Type field set to a value of 'M'. If one // does, then it already exists and there is nothing to do; if // not found, however, a new Address child must be added with a // Type field of 'M'. // // Lookup the IElementDef of relativeTo IElementDef subEleDef = Adk.Dtd.LookupElementDef(relativeTo.ElementDef, subEleTag); if (subEleDef == null) { subEleDef = Adk.Dtd.LookupElementDef(subEleTag); if (subEleDef == null) { throw new AdkSchemaException(subEleTag + " is not a recognized attribute of " + relativeTo.Tag); } } bool repeatable = subEleDef.IsRepeatable(relativeTo.SifVersion); SifElementList peers = relativeTo.GetChildList(subEleDef); if (curSegment.IndexOf("+]") == -1) { // // Determine if relatSifElementListiveTo has any children that already // define this attribute/value; if not, create a new instance. // If subEleDef is not repeatable, however, we cannot add // another instance of it regardless. // for (int i = 0; i < peers.Count && nextEle == null; i++) { SimpleField ftest = peers[i].GetField(attrName); if (ftest != null && ftest.TextValue.Equals(v)) { nextEle = peers[i]; } } } if (nextEle == null) { if (!(peers.Count > 0 && !repeatable)) { nextEle = _createChild(relativeTo, subEleTag, valueBuilder, version, textFormatter, pathFormatter); } else { // // subEleDef is not repeatable, so we need to back up // and add this attribute/value to a fresh instance of // relativeTo if possible. First use _xpath(path) to try // to select that instance in case it already exists (otherwise // we'd create a new instance each iteration, which is // not the desired result.) // string _tmp; if (path.Length > 0) { _tmp = path + "/" + curSegment; } else { _tmp = curSegment; } if (XPATH_DEBUG) { Console.Out.Write("Searching for path relative to " + relativeTo.Root.ElementDef.Name + ": " + _tmp); } int _del = _tmp.IndexOf('/'); nextEle = (SifElement) _xpath((SifElement)relativeTo.Root, _tmp.Substring(0, (_del == -1 ? _tmp.Length : _del) - (0)), _del == -1 ? null : _tmp.Substring(_del + 1)); if (XPATH_DEBUG) { if (nextEle == null) { Console.Out.WriteLine("; not found, a new instance will be created"); } else { Console.Out.WriteLine("; found"); } } if (nextEle == null) { if (relativeTo.ElementDef.IsRepeatable(relativeTo.SifVersion)) { // Clone relativeTo SifElement grandParent = (SifElement)relativeTo.Parent; nextEle = SifElement.Create(grandParent, relativeTo.ElementDef); pathFormatter.AddChild(grandParent, nextEle, version); // Clone subEleDef; this now becomes nextEle SifElement newEle = SifElement.Create(nextEle, subEleDef); pathFormatter.AddChild(nextEle, newEle, version); _copyAttributes(nextEle, prevAttributes); nextEle = newEle; } else { throw new AdkSchemaException( "It is not possible to create the element or attribute identified by this path: " + _tmp + (nextSegment == null ? "" : "/" + nextSegment) + ". The element or attribute is either undefined in this version of SIF, " + "or an attempt is being made to create another instance of an element that is not Repeatable."); } } } } } if (nextEle != null) { _createField(nextEle, attrName, v); } if (a == attrList.Length && nextEle == null) { return null; } } } else { // Search for the named attribute/element if (attr != -1) { SimpleField ff = relativeTo.GetField(curSegment.Substring(1)); if (ff == null) { ff = _createField(relativeTo, curSegment.Substring(1), null); } return ff; } else { string _tag = curSegment; int eq = curSegment.IndexOf('='); if (eq != -1) { _tag = curSegment.Substring(0, (eq) - (0)); } nextEle = relativeTo.GetChild(_tag); if (nextEle == null) { // The curSegment element does not exist as a child of the relativeTo // object, so create it. nextEle = _createChild(relativeTo, curSegment, valueBuilder, version, textFormatter, pathFormatter); if (nextEle == null) { if (nextSegment == null) { return relativeTo.GetField(_tag); } return null; } } } } // Continue the search if nextSegment has a value if (nextEle != null && (nextSegment != null && nextSegment.Length > 0)) { int i = nextSegment.IndexOf('/'); if (path.Length > 0) { path.Append("/"); } path.Append(curSegment); return _xpathBuild( nextEle, path, i == -1 ? nextSegment : nextSegment.Substring(0, (i)), i == -1 ? null : nextSegment.Substring(i + 1), _prevAttributes, valueBuilder, version, textFormatter, pathFormatter); } if (nextSegment == null && nextEle != null && (nextEle.TextValue == null || nextEle.TextValue.Length == 0)) { int eq2 = curSegment.LastIndexOf('='); if (eq2 != -1) { if (bracket == -1 || (curSegment.LastIndexOf(']') < eq2)) { // // An equals sign in the final segment indicates there is // a value constant or expression following the XPath // (e.g. "OtherId[@Type='06']=@pad($(PERMNUM),0,5)" ). Use // the user-supplied ValueBuilder to evaluate it. // string str = curSegment.Substring(eq2 + 1); nextEle.TextValue = valueBuilder == null ? str : valueBuilder.Evaluate(str); } } } return nextEle; }
/// <summary> Populate a SifDataObject from values in the supplied IDictionary. /// /// This form of the <c>map</c> method allows the caller to specify /// whether it is performing an inbound or outbound mapping operation, /// as well as the version of SIF associated with the SIF Data Object /// that's being mapped. These values are used to filter field mapping rules. /// The direction flag is also used to invoke automatic ValueSet /// translations on fields that have a <i>ValueSet</i> attribute. /// /// </summary> /// <param name="adaptor">An IFieldAdaptor that contains field values to assign to the /// supplied SifDataObject, where each entry in the map is keyed by the /// local application-defined name of a field and the value is the text /// value to assign to the corresponding element or attribute of the /// SifDataObject. /// /// </param> /// <param name="dataObject">The SifDataObject to assign field values to /// /// </param> /// <param name="valueBuilder">A custom ValueBuilder implementation to evaluate /// value expressions in XPath-like query strings /// /// </param> /// <param name="version">The SifVersion associated with the mapping operation. /// For inbound SIF_Event and SIF_Response messages, this value should /// be obtained by calling <c>getSIFVersion</c> on the /// <i>SifMessageInfo</i> parameter passed to the message handler. For /// inbound SIF_Request messages, it should be obtained by calling the /// <c>SifMessageInfo.getSIFRequestVersion</c> method. For /// outbound messages, this value should be obtained by calling /// <c>Adk.getSIFVersion</c> to get the version of SIF the class /// framework was initialized with. Note when this parameter is /// <c>null</c>, no SIF Version filtering will be applied to /// field mapping rules. /// /// </param> /// <exception cref="AdkMappingException"> thrown if an error occurs while /// evaluating a field rule</exception> public void MapOutbound(IFieldAdaptor adaptor, SifDataObject dataObject, IValueBuilder valueBuilder, SifVersion version) { ObjectMapping om = GetRules(dataObject.ElementDef.Tag(version), true); if (om != null) { SifXPathContext xpathContext = SifXPathContext.NewSIFContext(dataObject, version); if (adaptor is IXPathVariableLibrary) { xpathContext.AddVariables("", (IXPathVariableLibrary) adaptor); } IList<FieldMapping> list = GetRulesList(om, version, MappingDirection.Outbound); MapOutbound(xpathContext, adaptor, dataObject, list, valueBuilder, version); } }
public IValueBuilder Multiply(IValueBuilder other) => CreateValue(This, other, (l, r) => $"({l} * {r})");
/// <summary> Populate a SifDataObject from values in the supplied IDictionary. /// /// This form of the <c>map</c> method that accepts a custom /// <c>ValueBuilder</c> implementation to evaluate value expressions /// in XPath-like query strings. The <c>map</c> method uses the /// DefaultValueBuilder class as its built-in implementation, but you can /// supply your own by calling this method instead. /// /// </summary> /// <param name="adaptor">An IFieldAdaptor that contains field values to assign to the /// supplied SifDataObject, where each entry in the map is keyed by the /// local application-defined name of a field and the value is the text /// value to assign to the corresponding element or attribute of the /// SifDataObject. /// /// </param> /// <param name="adaptor">An IFieldAdaptor containing field values</param> /// <param name="data">The SifDataObject to assign field values to /// /// </param> /// <param name="valueBuilder">A custom ValueBuilder implementation to evaluate /// value expressions in XPath-like query strings /// /// </param> /// <exception cref="AdkMappingException"> thrown if an error occurs while /// evaluating a field rule /// </exception> public void MapOutbound(IFieldAdaptor adaptor, SifDataObject data, IValueBuilder valueBuilder) { MapOutbound(adaptor, data, valueBuilder, Adk.SifVersion); }
public IValueBuilder AsDividend(IValueBuilder divisor) => CreateValue(This, divisor, (l, r) => $"({l} / {r})");
public IntermediateModifierEntry WithValue(IValueBuilder value) { return new IntermediateModifierEntry(Form, Stat, value, Condition); }
public static String flattenDate( IValueBuilder vb, String dateString_in ) { ((TestValueBuilder) vb).WasCalled = true; return dateString_in.Replace( "-", "" ).Trim(); }