예제 #1
0
        // 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 ArrayList();

            // convert all attributes to iterators even if just one value
            for (int a = 0; a < attributes.Count; a++)
            {
                Object o = attributes[a];
                o = convertAnythingToIterator(o);
                attributes[a] = o;
            }

            int numAttributes = attributes.Count;

            // ensure arguments line up
            IDictionary formalArguments = templateToApply.getFormalArguments();
            if ( formalArguments==null || formalArguments.Count==0 )
            {
                self.error("missing arguments in anonymous"+
                    " template in context "+self.getEnclosingInstanceStackString());
                return null;
            }
            ICollection keys = formalArguments.Keys;
            Object[] formalArgumentNames = new object[keys.Count];
            keys.CopyTo(formalArgumentNames,0);
            if ( formalArgumentNames.Length!=numAttributes )
            {
                self.error("number of arguments "+SupportClass.CollectionToString(formalArguments.Keys)+
                    " 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];
                System.Array.Copy(formalArgumentNames, 0,
                    newFormalArgumentNames, 0,
                    shorterSize);
                formalArgumentNames = newFormalArgumentNames;
            }

            // keep walking while at least one attribute has values
            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.MoveNext() )
                    {
                        String argName = (String)formalArgumentNames[a];
                        Object iteratedValue = it.Current;
                        argumentContext[argName] = iteratedValue;
                    }
                    else
                    {
                        numEmpty++;
                    }
                }
                if ( numEmpty==numAttributes )
                {
                    break;
                }
                StringTemplate embedded = templateToApply.getInstanceOf();
                embedded.setEnclosingInstance(self);
                embedded.setArgumentContext(argumentContext);
                results.Add(embedded);
            }

            return results;
        }