Merge pull request #4248 from Unity-Technologies/boehm-gc-alloc-fixed
[mono.git] / mcs / class / referencesource / System.Xml / System / Xml / Xslt / XslTransform.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XslTransform.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">[....]</owner>
6 //------------------------------------------------------------------------------
7
8 namespace System.Xml.Xsl {
9     using System.Reflection;
10     using System.Diagnostics;
11     using System.IO;
12     using System.Xml.XPath;
13     using System.Xml.Xsl.XsltOld;
14     using MS.Internal.Xml.XPath;
15     using MS.Internal.Xml.Cache;
16     using System.Collections.Generic;
17     using System.Xml.Xsl.XsltOld.Debugger;
18     using System.Security.Policy;
19     using System.Security.Permissions;
20     using System.Runtime.Versioning;
21     using System.Xml.XmlConfiguration;
22
23     [Obsolete("This class has been deprecated. Please use System.Xml.Xsl.XslCompiledTransform instead. http://go.microsoft.com/fwlink/?linkid=14202")]
24     public sealed class XslTransform {
25         private XmlResolver _documentResolver = null;
26         private bool isDocumentResolverSet = false;
27         private XmlResolver _DocumentResolver {
28             get {
29                 if (isDocumentResolverSet)
30                     return _documentResolver;
31                 else
32                     return XsltConfigSection.CreateDefaultResolver();
33             }
34         }
35
36
37         //
38         // Compiled stylesheet state
39         //
40         private Stylesheet  _CompiledStylesheet;
41         private List<TheQuery>   _QueryStore;
42         private RootAction  _RootAction;
43
44         private IXsltDebugger debugger;
45
46         public XslTransform() {}
47
48         public XmlResolver XmlResolver {
49             set {
50                 _documentResolver = value;
51                 isDocumentResolverSet = true;
52             }
53         }
54
55         public void Load(XmlReader stylesheet) {
56             Load(stylesheet, XsltConfigSection.CreateDefaultResolver());
57         }
58         public void Load(XmlReader stylesheet, XmlResolver resolver) {
59             Load(new XPathDocument(stylesheet, XmlSpace.Preserve), resolver);
60         }
61
62         public void Load(IXPathNavigable stylesheet) {
63             Load(stylesheet, XsltConfigSection.CreateDefaultResolver());
64         }
65         public void Load(IXPathNavigable stylesheet, XmlResolver resolver) {
66             if (stylesheet == null) {
67                 throw new ArgumentNullException("stylesheet");
68             }
69             Load(stylesheet.CreateNavigator(), resolver);
70         }
71
72         public void Load(XPathNavigator stylesheet) {
73             if (stylesheet == null) {
74                 throw new ArgumentNullException("stylesheet");
75             }
76             Load(stylesheet, XsltConfigSection.CreateDefaultResolver());
77         }
78         public void Load(XPathNavigator stylesheet, XmlResolver resolver) {
79             if (stylesheet == null) {
80                 throw new ArgumentNullException("stylesheet");
81             }
82             Compile(stylesheet, resolver, /*evidence:*/null);
83         }
84
85         [ResourceConsumption(ResourceScope.Machine)]
86         [ResourceExposure(ResourceScope.Machine)]
87         public void Load(string url) {
88             XmlTextReaderImpl tr = new XmlTextReaderImpl(url);
89             Evidence evidence = XmlSecureResolver.CreateEvidenceForUrl(tr.BaseURI); // We should ask BaseURI before we start reading because it's changing with each node
90             Compile(Compiler.LoadDocument(tr).CreateNavigator(), XsltConfigSection.CreateDefaultResolver(), evidence);
91         }
92
93         [ResourceConsumption(ResourceScope.Machine)]
94         [ResourceExposure(ResourceScope.Machine)]
95         public void Load(string url, XmlResolver resolver) {
96             XmlTextReaderImpl tr = new XmlTextReaderImpl(url); {
97                 tr.XmlResolver = resolver;
98             }
99             Evidence evidence = XmlSecureResolver.CreateEvidenceForUrl(tr.BaseURI); // We should ask BaseURI before we start reading because it's changing with each node
100             Compile(Compiler.LoadDocument(tr).CreateNavigator(), resolver, evidence);
101         }
102
103         public void Load(IXPathNavigable stylesheet, XmlResolver resolver, Evidence evidence) {
104             if (stylesheet == null) {
105                 throw new ArgumentNullException("stylesheet");
106             }
107             Load(stylesheet.CreateNavigator(), resolver, evidence);
108         }
109         public void Load(XmlReader stylesheet, XmlResolver resolver, Evidence evidence) {
110             if (stylesheet == null) {
111                 throw new ArgumentNullException("stylesheet");
112             }
113             Load(new XPathDocument(stylesheet, XmlSpace.Preserve), resolver, evidence);
114         }
115         public void Load(XPathNavigator stylesheet, XmlResolver resolver, Evidence evidence) {
116             if (stylesheet == null) {
117                 throw new ArgumentNullException("stylesheet");
118             }
119 #if MONO_FEATURE_CAS
120             if (evidence == null) {
121                 evidence = new Evidence();
122             }
123             else {
124                 new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
125             }
126 #endif
127             Compile(stylesheet, resolver, evidence);
128         }
129
130         // ------------------------------------ Transform() ------------------------------------ //
131
132         private void CheckCommand() {
133             if (_CompiledStylesheet == null) {
134                 throw new InvalidOperationException(Res.GetString(Res.Xslt_NoStylesheetLoaded));
135             }
136         }
137
138         public XmlReader Transform(XPathNavigator input, XsltArgumentList args, XmlResolver resolver) {
139             CheckCommand();
140             Processor processor = new Processor(input, args, resolver, _CompiledStylesheet, _QueryStore, _RootAction, debugger);
141             return processor.StartReader();
142         }
143
144         public XmlReader Transform(XPathNavigator input, XsltArgumentList args) {
145             return Transform(input, args, _DocumentResolver);
146         }
147
148         public void Transform(XPathNavigator input, XsltArgumentList args, XmlWriter output, XmlResolver resolver) {
149             CheckCommand();
150             Processor processor = new Processor(input, args, resolver, _CompiledStylesheet, _QueryStore, _RootAction, debugger);
151             processor.Execute(output);
152         }
153
154         public void Transform(XPathNavigator input, XsltArgumentList args, XmlWriter output) {
155             Transform(input, args, output, _DocumentResolver);
156         }
157         public void Transform(XPathNavigator input, XsltArgumentList args, Stream output, XmlResolver resolver) {
158             CheckCommand();
159             Processor processor = new Processor(input, args, resolver, _CompiledStylesheet, _QueryStore, _RootAction, debugger);
160             processor.Execute(output);
161         }
162
163         public void Transform(XPathNavigator input, XsltArgumentList args, Stream output) {
164             Transform(input, args, output, _DocumentResolver);
165         }
166
167         public void Transform(XPathNavigator input, XsltArgumentList args, TextWriter output, XmlResolver resolver) {
168             CheckCommand();
169             Processor processor = new Processor(input, args, resolver, _CompiledStylesheet, _QueryStore, _RootAction, debugger);
170             processor.Execute(output);
171         }
172
173         public void Transform(XPathNavigator input, XsltArgumentList args, TextWriter output) {
174             CheckCommand();
175             Processor processor = new Processor(input, args, _DocumentResolver, _CompiledStylesheet, _QueryStore, _RootAction, debugger);
176             processor.Execute(output);
177         }
178
179         public XmlReader Transform(IXPathNavigable input, XsltArgumentList args, XmlResolver resolver) {
180             if (input == null) {
181                 throw new ArgumentNullException("input");
182             }
183             return Transform(input.CreateNavigator(), args, resolver);
184         }
185
186         public XmlReader Transform(IXPathNavigable input, XsltArgumentList args) {
187             if (input == null) {
188                 throw new ArgumentNullException("input");
189             }
190             return Transform(input.CreateNavigator(), args, _DocumentResolver);
191         }
192         public void Transform(IXPathNavigable input, XsltArgumentList args, TextWriter output, XmlResolver resolver) {
193             if (input == null) {
194                 throw new ArgumentNullException("input");
195             }
196             Transform(input.CreateNavigator(), args, output, resolver);
197         }
198
199         public void Transform(IXPathNavigable input, XsltArgumentList args, TextWriter output) {
200             if (input == null) {
201                 throw new ArgumentNullException("input");
202             }
203             Transform(input.CreateNavigator(), args, output, _DocumentResolver);
204         }
205
206         public void Transform(IXPathNavigable input, XsltArgumentList args, Stream output, XmlResolver resolver) {
207             if (input == null) {
208                 throw new ArgumentNullException("input");
209             }
210             Transform(input.CreateNavigator(), args, output, resolver);
211         }
212
213         public void Transform(IXPathNavigable input, XsltArgumentList args, Stream output) {
214             if (input == null) {
215                 throw new ArgumentNullException("input");
216             }
217             Transform(input.CreateNavigator(), args, output, _DocumentResolver);
218         }
219
220         public void Transform(IXPathNavigable input, XsltArgumentList args, XmlWriter output, XmlResolver resolver) {
221             if (input == null) {
222                 throw new ArgumentNullException("input");
223             }
224             Transform(input.CreateNavigator(), args, output, resolver);
225         }
226
227         public void Transform(IXPathNavigable input, XsltArgumentList args, XmlWriter output) {
228             if (input == null) {
229                 throw new ArgumentNullException("input");
230             }
231             Transform(input.CreateNavigator(), args, output, _DocumentResolver);
232         }
233
234         [ResourceConsumption(ResourceScope.Machine)]
235         [ResourceExposure(ResourceScope.Machine)]
236         public void Transform(String inputfile, String outputfile, XmlResolver resolver) {
237             FileStream fs = null;
238             try {
239                 // We should read doc before creating output file in case they are the same
240                 XPathDocument doc = new XPathDocument(inputfile);
241                 fs = new FileStream(outputfile, FileMode.Create, FileAccess.ReadWrite);
242                 Transform(doc, /*args:*/null, fs, resolver);
243             }
244             finally {
245                 if (fs != null) {
246                     fs.Close();
247                 }
248             }
249             }
250
251         [ResourceConsumption(ResourceScope.Machine)]
252         [ResourceExposure(ResourceScope.Machine)]
253         public void Transform(String inputfile, String outputfile) {
254             Transform(inputfile, outputfile, _DocumentResolver);
255         }
256
257         // Implementation
258
259         private void Compile(XPathNavigator stylesheet, XmlResolver resolver, Evidence evidence) {
260             Debug.Assert(stylesheet != null);
261
262             Compiler  compiler = (Debugger == null) ? new Compiler() : new DbgCompiler(this.Debugger);
263             NavigatorInput input = new NavigatorInput(stylesheet);
264             compiler.Compile(input, resolver ?? XmlNullResolver.Singleton, evidence);
265
266             Debug.Assert(compiler.CompiledStylesheet != null);
267             Debug.Assert(compiler.QueryStore != null);
268             Debug.Assert(compiler.QueryStore != null);
269             _CompiledStylesheet = compiler.CompiledStylesheet;
270             _QueryStore         = compiler.QueryStore;
271             _RootAction         = compiler.RootAction;
272         }
273
274         internal IXsltDebugger Debugger {
275             get { return this.debugger; }
276         }
277
278 #if false
279         internal XslTransform(IXsltDebugger debugger) {
280             this.debugger = debugger;
281         }
282 #endif
283
284         internal XslTransform(object debugger) {
285             if (debugger != null) {
286                 this.debugger = new DebuggerAddapter(debugger);
287             }
288         }
289
290         private class DebuggerAddapter : IXsltDebugger {
291             private object unknownDebugger;
292             private MethodInfo getBltIn;
293             private MethodInfo onCompile;
294             private MethodInfo onExecute;
295             public DebuggerAddapter(object unknownDebugger) {
296                 this.unknownDebugger = unknownDebugger;
297                 BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
298                 Type unknownType = unknownDebugger.GetType();
299                 getBltIn  = unknownType.GetMethod("GetBuiltInTemplatesUri", flags);
300                 onCompile = unknownType.GetMethod("OnInstructionCompile"  , flags);
301                 onExecute = unknownType.GetMethod("OnInstructionExecute"  , flags);
302             }
303             // ------------------ IXsltDebugger ---------------
304             public string GetBuiltInTemplatesUri() {
305                 if (getBltIn == null) {
306                     return null;
307                 }
308                 return (string) getBltIn.Invoke(unknownDebugger, new object[] {});
309             }
310             public void OnInstructionCompile(XPathNavigator styleSheetNavigator) {
311                 if (onCompile != null) {
312                     onCompile.Invoke(unknownDebugger, new object[] { styleSheetNavigator });
313                 }
314             }
315             public void OnInstructionExecute(IXsltProcessor xsltProcessor) {
316                 if (onExecute != null) {
317                     onExecute.Invoke(unknownDebugger, new object[] { xsltProcessor });
318                 }
319             }
320         }
321     }
322 }