The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.XsltOld \ SortAction

  1. //------------------------------------------------------------------------------
  2. // <copyright file="SortAction.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Xml.Xsl.XsltOld
  16. {
  17.     using Res = System.Xml.Utils.Res;
  18.     using System;
  19.     using System.Diagnostics;
  20.     using System.Xml;
  21.     using System.Xml.XPath;
  22.    
  23.     internal class SortAction : CompiledAction
  24.     {
  25.         private int selectKey = Compiler.InvalidQueryKey;
  26.         private Avt langAvt;
  27.         private Avt dataTypeAvt;
  28.         private Avt orderAvt;
  29.         private Avt caseOrderAvt;
  30.         // Compile time precalculated AVTs
  31.         private string lang;
  32.         private XmlDataType dataType = XmlDataType.Text;
  33.         private XmlSortOrder order = XmlSortOrder.Ascending;
  34.         private XmlCaseOrder caseOrder = XmlCaseOrder.None;
  35.         private Sort sort;
  36.         //When we not have AVTs at all we can do this. null otherwise.
  37.         private bool forwardCompatibility;
  38.         private InputScopeManager manager;
  39.        
  40.         private string ParseLang(string value)
  41.         {
  42.             if (value == null) {
  43.                 // Avt is not constant, or attribute wasn't defined
  44.                 return null;
  45.             }
  46.             if (!XmlComplianceUtil.IsValidLanguageID(value.ToCharArray(), 0, value.Length)) {
  47.                 if (this.forwardCompatibility) {
  48.                     return null;
  49.                 }
  50.                 throw XsltException.Create(Res.Xslt_InvalidAttrValue, Keywords.s_Lang, value);
  51.             }
  52.             return value;
  53.         }
  54.        
  55.         private XmlDataType ParseDataType(string value, InputScopeManager manager)
  56.         {
  57.             if (value == null) {
  58.                 // Avt is not constant, or attribute wasn't defined
  59.                 return XmlDataType.Text;
  60.             }
  61.             if (value == Keywords.s_Text) {
  62.                 return XmlDataType.Text;
  63.             }
  64.             if (value == Keywords.s_Number) {
  65.                 return XmlDataType.Number;
  66.             }
  67.             string prefix;
  68.             string localname;
  69.             PrefixQName.ParseQualifiedName(value, out prefix, out localname);
  70.             manager.ResolveXmlNamespace(prefix);
  71.             if (prefix.Length == 0 && !this.forwardCompatibility) {
  72.                 throw XsltException.Create(Res.Xslt_InvalidAttrValue, Keywords.s_DataType, value);
  73.             }
  74.             return XmlDataType.Text;
  75.         }
  76.        
  77.         private XmlSortOrder ParseOrder(string value)
  78.         {
  79.             if (value == null) {
  80.                 // Avt is not constant, or attribute wasn't defined
  81.                 return XmlSortOrder.Ascending;
  82.             }
  83.             if (value == Keywords.s_Ascending) {
  84.                 return XmlSortOrder.Ascending;
  85.             }
  86.             if (value == Keywords.s_Descending) {
  87.                 return XmlSortOrder.Descending;
  88.             }
  89.             if (this.forwardCompatibility) {
  90.                 return XmlSortOrder.Ascending;
  91.             }
  92.             throw XsltException.Create(Res.Xslt_InvalidAttrValue, Keywords.s_Order, value);
  93.         }
  94.        
  95.         private XmlCaseOrder ParseCaseOrder(string value)
  96.         {
  97.             if (value == null) {
  98.                 // Avt is not constant, or attribute wasn't defined
  99.                 return XmlCaseOrder.None;
  100.             }
  101.             if (value == Keywords.s_UpperFirst) {
  102.                 return XmlCaseOrder.UpperFirst;
  103.             }
  104.             if (value == Keywords.s_LowerFirst) {
  105.                 return XmlCaseOrder.LowerFirst;
  106.             }
  107.             if (this.forwardCompatibility) {
  108.                 return XmlCaseOrder.None;
  109.             }
  110.             throw XsltException.Create(Res.Xslt_InvalidAttrValue, Keywords.s_CaseOrder, value);
  111.         }
  112.        
  113.         internal override void Compile(Compiler compiler)
  114.         {
  115.             CompileAttributes(compiler);
  116.             CheckEmpty(compiler);
  117.             if (selectKey == Compiler.InvalidQueryKey) {
  118.                 selectKey = compiler.AddQuery(".");
  119.             }
  120.            
  121.             this.forwardCompatibility = compiler.ForwardCompatibility;
  122.             this.manager = compiler.CloneScopeManager();
  123.            
  124.             this.lang = ParseLang(PrecalculateAvt(ref this.langAvt));
  125.             this.dataType = ParseDataType(PrecalculateAvt(ref this.dataTypeAvt), manager);
  126.             this.order = ParseOrder(PrecalculateAvt(ref this.orderAvt));
  127.             this.caseOrder = ParseCaseOrder(PrecalculateAvt(ref this.caseOrderAvt));
  128.            
  129.             if (this.langAvt == null && this.dataTypeAvt == null && this.orderAvt == null && this.caseOrderAvt == null) {
  130.                 this.sort = new Sort(this.selectKey, this.lang, this.dataType, this.order, this.caseOrder);
  131.             }
  132.         }
  133.        
  134.         internal override bool CompileAttribute(Compiler compiler)
  135.         {
  136.             string name = compiler.Input.LocalName;
  137.             string value = compiler.Input.Value;
  138.            
  139.             if (Keywords.Equals(name, compiler.Atoms.Select)) {
  140.                 this.selectKey = compiler.AddQuery(value);
  141.             }
  142.             else if (Keywords.Equals(name, compiler.Atoms.Lang)) {
  143.                 this.langAvt = Avt.CompileAvt(compiler, value);
  144.             }
  145.             else if (Keywords.Equals(name, compiler.Atoms.DataType)) {
  146.                 this.dataTypeAvt = Avt.CompileAvt(compiler, value);
  147.             }
  148.             else if (Keywords.Equals(name, compiler.Atoms.Order)) {
  149.                 this.orderAvt = Avt.CompileAvt(compiler, value);
  150.             }
  151.             else if (Keywords.Equals(name, compiler.Atoms.CaseOrder)) {
  152.                 this.caseOrderAvt = Avt.CompileAvt(compiler, value);
  153.             }
  154.             else {
  155.                 return false;
  156.             }
  157.             return true;
  158.         }
  159.        
  160.         internal override void Execute(Processor processor, ActionFrame frame)
  161.         {
  162.             Debug.Assert(processor != null && frame != null);
  163.             Debug.Assert(frame.State == Initialized);
  164.            
  165.             processor.AddSort(this.sort != null ? this.sort : new Sort(this.selectKey, this.langAvt == null ? this.lang : ParseLang(this.langAvt.Evaluate(processor, frame)), this.dataTypeAvt == null ? this.dataType : ParseDataType(this.dataTypeAvt.Evaluate(processor, frame), manager), this.orderAvt == null ? this.order : ParseOrder(this.orderAvt.Evaluate(processor, frame)), this.caseOrderAvt == null ? this.caseOrder : ParseCaseOrder(this.caseOrderAvt.Evaluate(processor, frame))));
  166.             frame.Finished();
  167.         }
  168.     }
  169. }

Developer Fusion