internal static IEnumerator ConvertAnythingToIterator(object o) { IEnumerator iter = null; if (o is IDictionary) { iter = ((IDictionary) o).Values.GetEnumerator(); } else if (o is ICollection) { iter = ((ICollection) o).GetEnumerator(); } else if (o is IEnumerator) { iter = (IEnumerator) o; } if (iter == null) { IList singleton = new StringTemplate.STAttributeList(1); singleton.Add(o); return singleton.GetEnumerator(); } return iter; }
// HELP ROUTINES CALLED BY EVALUATOR TREE WALKER /// <summary> /// For <names,phones:{n,p | ...}> treat the names, phones as lists /// to be walked in lock step as n=names[i], p=phones[i]. /// </summary> public virtual object ApplyTemplateToListOfAttributes(StringTemplate self, IList attributes, StringTemplate templateToApply) { if (attributes == null || templateToApply == null || attributes.Count == 0) { return null; // do not apply if missing templates or empty values } IDictionary argumentContext = null; IList results = new StringTemplate.STAttributeList(); // convert all attributes to iterators even if just one value for (int a = 0; a < attributes.Count; a++) { object o = (object) attributes[a]; if (o != null) { o = ConvertAnythingToIterator(o); attributes[a] = o; // alter the list in place } } int numAttributes = attributes.Count; // ensure arguments line up HashList formalArguments = (HashList) templateToApply.FormalArguments; if (formalArguments == null || formalArguments.Count == 0) { self.Error("missing arguments in anonymous" + " template in context " + self.GetEnclosingInstanceStackString()); return null; } object[] formalArgumentNames = new object[formalArguments.Count]; formalArguments.Keys.CopyTo(formalArgumentNames, 0); if (formalArgumentNames.Length != numAttributes) { self.Error("number of arguments " + formalArguments.Keys.ToString() + " mismatch between attribute list and anonymous" + " template in context " + self.GetEnclosingInstanceStackString()); // truncate arg list to match smaller size int shorterSize = Math.Min(formalArgumentNames.Length, numAttributes); numAttributes = shorterSize; object[] newFormalArgumentNames = new object[shorterSize]; Array.Copy(formalArgumentNames, 0, newFormalArgumentNames, 0, shorterSize); formalArgumentNames = newFormalArgumentNames; } // keep walking while at least one attribute has values int i = 0; // iteration number from 0 while (true) { argumentContext = new Hashtable(); // get a value for each attribute in list; put into arg context // to simulate template invocation of anonymous template int numEmpty = 0; for (int a = 0; a < numAttributes; a++) { IEnumerator it = (IEnumerator) attributes[a]; if ((it != null) && it.MoveNext()) { string argName = (string) formalArgumentNames[a]; object iteratedValue = it.Current; argumentContext[argName] = iteratedValue; } else { numEmpty++; } } if (numEmpty == numAttributes) { break; } argumentContext[DEFAULT_INDEX_VARIABLE_NAME] = i+1; argumentContext[DEFAULT_INDEX0_VARIABLE_NAME] = i; StringTemplate embedded = templateToApply.GetInstanceOf(); embedded.EnclosingInstance = self; embedded.ArgumentContext = argumentContext; results.Add(embedded); i++; } return results; }
public virtual object ApplyListOfAlternatingTemplates(StringTemplate self, object attributeValue, IList templatesToApply) { if (attributeValue == null || templatesToApply == null || templatesToApply.Count == 0) { return null; // do not apply if missing templates or empty value } StringTemplate embedded = null; IDictionary argumentContext = null; // normalize collections and such to use iterators // anything iteratable can be used for "APPLY" // TODO: 2006-08-05 - Needed?: attributeValue = convertArrayToList(attributeValue); attributeValue = ConvertAnythingIteratableToIterator(attributeValue); bool isAnonymous; bool hasFormalArgument; if (attributeValue is IEnumerator) { // results can be treated list an attribute, indicate ST created list IList resultVector = new StringTemplate.STAttributeList(); IEnumerator iter = (IEnumerator) attributeValue; int i = 0; while (iter.MoveNext()) { object ithValue = iter.Current; if (ithValue == null) { if (nullValue == null) { continue; } ithValue = nullValue; } int templateIndex = i % templatesToApply.Count; // rotate through embedded = (StringTemplate) templatesToApply[templateIndex]; // template to apply is an actual StringTemplate (created in // eval.g), but that is used as the examplar. We must create // a new instance of the embedded template to apply each time // to get new attribute sets etc... StringTemplateAST args = embedded.ArgumentsAST; embedded = embedded.GetInstanceOf(); // make new instance embedded.EnclosingInstance = self; embedded.ArgumentsAST = args; argumentContext = new Hashtable(); isAnonymous = (embedded.Name == StringTemplate.ANONYMOUS_ST_NAME); IDictionary formalArgs = embedded.FormalArguments; SetSoleFormalArgumentToIthValue(embedded, argumentContext, ithValue); hasFormalArgument = ((formalArgs != null) && (formalArgs.Count > 0)); // if it's an anonymous template with a formal arg, don't set it/attr if ( !(isAnonymous && hasFormalArgument) ) { argumentContext[DEFAULT_ATTRIBUTE_NAME] = ithValue; argumentContext[DEFAULT_ATTRIBUTE_NAME_DEPRECATED] = ithValue; } argumentContext[DEFAULT_INDEX_VARIABLE_NAME] = (i + 1); argumentContext[DEFAULT_INDEX0_VARIABLE_NAME] = i; embedded.ArgumentContext = argumentContext; EvaluateArguments(embedded); /* System.err.println("i="+i+": applyTemplate("+embedded.getName()+ ", args="+argumentContext+ " to attribute value "+ithValue); */ resultVector.Add(embedded); i++; } if (resultVector.Count == 0) { resultVector = null; } return resultVector; } else { /* System.out.println("setting attribute "+DEFAULT_ATTRIBUTE_NAME+" in arg context of "+ embedded.getName()+ " to "+attributeValue); */ embedded = (StringTemplate) templatesToApply[0]; argumentContext = new Hashtable(); IDictionary formalArgs = embedded.FormalArguments; SetSoleFormalArgumentToIthValue(embedded, argumentContext, attributeValue); isAnonymous = (embedded.Name == StringTemplate.ANONYMOUS_ST_NAME); hasFormalArgument = ((formalArgs != null) && (formalArgs.Count > 0)); // if it's an anonymous template with a formal arg, don't set it/attr if ( !(isAnonymous && hasFormalArgument) ) { argumentContext[DEFAULT_ATTRIBUTE_NAME] = attributeValue; argumentContext[DEFAULT_ATTRIBUTE_NAME_DEPRECATED] = attributeValue; } argumentContext[DEFAULT_INDEX_VARIABLE_NAME] = 1; argumentContext[DEFAULT_INDEX0_VARIABLE_NAME] = 0; embedded.ArgumentContext = argumentContext; EvaluateArguments(embedded); return embedded; } }
/** <summary> * For <names,phones:{n,p | ...}> treat the names, phones as lists * to be walked in lock step as n=names[i], p=phones[i]. * </summary> */ public virtual object ApplyTemplateToListOfAttributes( StringTemplate self, IList attributes, StringTemplate templateToApply ) { if ( attributes == null || templateToApply == null || attributes.Count == 0 ) { return null; // do not apply if missing templates or empty values } Dictionary<string, object> argumentContext = null; // indicate it's an ST-created list var results = new StringTemplate.STAttributeList(); // convert all attributes to iterators even if just one value for ( int a = 0; a < attributes.Count; a++ ) { object o = attributes[a]; if ( o != null ) { o = ConvertAnythingToIterator( o ); attributes[a] = o; // alter the list in place } } int numAttributes = attributes.Count; // ensure arguments line up var formalArguments = templateToApply.FormalArguments; if ( formalArguments == null || formalArguments.Count == 0 ) { self.Error( "missing arguments in anonymous" + " template in context " + self.GetEnclosingInstanceStackString() ); return null; } string[] formalArgumentNames = formalArguments.Select( fa => fa.name ).ToArray(); if ( formalArgumentNames.Length != numAttributes ) { string formalArgumentsText = formalArguments.Select( fa => fa.name ).ToList().ToElementString(); self.Error( "number of arguments " + formalArgumentsText + " mismatch between attribute list and anonymous" + " template in context " + self.GetEnclosingInstanceStackString() ); // truncate arg list to match smaller size int shorterSize = Math.Min( formalArgumentNames.Length, numAttributes ); numAttributes = shorterSize; string[] newFormalArgumentNames = new string[shorterSize]; Array.Copy( formalArgumentNames, 0, newFormalArgumentNames, 0, shorterSize ); formalArgumentNames = newFormalArgumentNames; } // keep walking while at least one attribute has values int i = 0; // iteration number from 0 for ( ; ; ) { argumentContext = new Dictionary<string, object>(); // get a value for each attribute in list; put into arg context // to simulate template invocation of anonymous template int numEmpty = 0; for ( int a = 0; a < numAttributes; a++ ) { Iterator it = attributes[a] as Iterator; if ( it != null && it.hasNext() ) { string argName = formalArgumentNames[a]; object iteratedValue = it.next(); argumentContext[argName] = iteratedValue; } else { numEmpty++; } } if ( numEmpty == numAttributes ) { break; } argumentContext[DefaultIndexVariableName] = i + 1; argumentContext[DefaultIndex0VariableName] = i; StringTemplate embedded = templateToApply.GetInstanceOf(); embedded.EnclosingInstance = self; embedded.ArgumentContext = argumentContext; results.Add( embedded ); i++; } return results; }
public virtual object ApplyListOfAlternatingTemplates( StringTemplate self, object attributeValue, IList<StringTemplate> templatesToApply ) { if ( attributeValue == null || templatesToApply == null || templatesToApply.Count == 0 ) { return null; // do not apply if missing templates or empty value } StringTemplate embedded = null; Dictionary<string, object> argumentContext = null; // normalize collections and such to use iterators // anything iteratable can be used for "APPLY" attributeValue = ConvertArrayToList( attributeValue ); attributeValue = ConvertAnythingIteratableToIterator( attributeValue ); Iterator iter = attributeValue as Iterator; if ( iter != null ) { // results can be treated list an attribute, indicate ST created list var resultVector = new StringTemplate.STAttributeList(); int i = 0; while ( iter.hasNext() ) { object ithValue = iter.next(); if ( ithValue == null ) { if ( _nullValue == null ) { continue; } ithValue = _nullValue; } int templateIndex = i % templatesToApply.Count; // rotate through embedded = templatesToApply[templateIndex]; // template to apply is an actual StringTemplate (created in // eval.g), but that is used as the examplar. We must create // a new instance of the embedded template to apply each time // to get new attribute sets etc... StringTemplateAST args = embedded.ArgumentsAST; embedded = embedded.GetInstanceOf(); // make new instance embedded.EnclosingInstance = self; embedded.ArgumentsAST = args; argumentContext = new Dictionary<string, object>(); var formalArgs = embedded.FormalArguments; bool isAnonymous = embedded.Name == StringTemplate.ANONYMOUS_ST_NAME; SetSoleFormalArgumentToIthValue( embedded, argumentContext, ithValue ); // if it's an anonymous template with a formal arg, don't set it/attr if ( !( isAnonymous && formalArgs != null && formalArgs.Count > 0 ) ) { argumentContext[DefaultAttributeName] = ithValue; argumentContext[DefaultAttributeNameDeprecated] = ithValue; } argumentContext[DefaultIndexVariableName] = i + 1; argumentContext[DefaultIndex0VariableName] = i; embedded.ArgumentContext = argumentContext; EvaluateArguments( embedded ); /* System.err.println("i="+i+": applyTemplate("+embedded.getName()+ ", args="+argumentContext+ " to attribute value "+ithValue); */ resultVector.Add( embedded ); i++; } if ( resultVector.Count == 0 ) { resultVector = null; } return resultVector; } else { /* System.out.println("setting attribute "+DEFAULT_ATTRIBUTE_NAME+" in arg context of "+ embedded.getName()+ " to "+attributeValue); */ embedded = templatesToApply[0]; argumentContext = new Dictionary<string, object>(); var formalArgs = embedded.FormalArguments; StringTemplateAST args = embedded.ArgumentsAST; SetSoleFormalArgumentToIthValue( embedded, argumentContext, attributeValue ); bool isAnonymous = embedded.Name == StringTemplate.ANONYMOUS_ST_NAME; // if it's an anonymous template with a formal arg, don't set it/attr if ( !( isAnonymous && formalArgs != null && formalArgs.Count > 0 ) ) { argumentContext[DefaultAttributeName] = attributeValue; argumentContext[DefaultAttributeNameDeprecated] = attributeValue; } argumentContext[DefaultIndexVariableName] = 1; argumentContext[DefaultIndex0VariableName] = 0; embedded.ArgumentContext = argumentContext; EvaluateArguments( embedded ); return embedded; } }
protected static Iterator ConvertAnythingToIterator( object o ) { o = ConvertAnythingIteratableToIterator( o ); Iterator iter = o as Iterator; if ( iter != null ) return iter; var singleton = new StringTemplate.STAttributeList( 1 ); singleton.Add( o ); return singleton.iterator(); }