Project

Profile

Help

How to connect?
Download (127 KB) Statistics
| Branch: | Revision:

he / src / main / csharp / api / Saxon.Api / Xslt.cs @ 2699858e

1
using System;
2
using System.IO;
3
using System.Xml;
4
using System.Collections;
5
using System.Collections.Generic;
6
using System.Globalization;
7
using JStreamSource = javax.xml.transform.stream.StreamSource;
8
using JResult = javax.xml.transform.Result;
9
using JTransformerException = javax.xml.transform.TransformerException;
10
using JOutputURIResolver = net.sf.saxon.lib.OutputURIResolver;
11
using JConfiguration = net.sf.saxon.Configuration;
12
using JPipelineConfiguration = net.sf.saxon.@event.PipelineConfiguration;
13
using JSequenceWriter = net.sf.saxon.@event.SequenceWriter;
14
using JReceiver = net.sf.saxon.@event.Receiver;
15
//using JReceiverOptions = net.sf.saxon.@event.ReceiverOptions;
16
using JCompilerInfo = net.sf.saxon.trans.CompilerInfo;
17
using JExpressionPresenter = net.sf.saxon.trace.ExpressionPresenter;
18
using JValidation = net.sf.saxon.lib.Validation;
19
using JValidationMode = net.sf.saxon.s9api.ValidationMode;
20
using JCompilation = net.sf.saxon.style.Compilation;
21
using JController = net.sf.saxon.Controller;
22
using JXsltController = net.sf.saxon.trans.XsltController;
23
using JItem = net.sf.saxon.om.Item;
24
using JNodeInfo = net.sf.saxon.om.NodeInfo;
25
using JNodeName = net.sf.saxon.om.NodeName;
26
using JSchemaType = net.sf.saxon.type.SchemaType;
27
using JTreeInfo = net.sf.saxon.om.TreeInfo;
28
using JPullSource = net.sf.saxon.pull.PullSource;
29
using JProcInstParser = net.sf.saxon.tree.util.ProcInstParser;
30
using JXsltCompiler = net.sf.saxon.s9api.XsltCompiler;
31
using JXsltExecutable = net.sf.saxon.s9api.XsltExecutable;
32
using JSaxonApiException = net.sf.saxon.s9api.SaxonApiException;
33
using JDotNetComparator = net.sf.saxon.dotnet.DotNetComparator;
34
using JDotNetURIResolver = net.sf.saxon.dotnet.DotNetURIResolver;
35
using JDotNetInputStream = net.sf.saxon.dotnet.DotNetInputStream;
36
using JDotNetReader = net.sf.saxon.dotnet.DotNetReader;
37
using JDotNetPullProvider = net.sf.saxon.dotnet.DotNetPullProvider;
38
using CharSequence = java.lang.CharSequence;
39
using JXsltTransformer = net.sf.saxon.s9api.XsltTransformer;
40
using JXslt30Transformer = net.sf.saxon.s9api.Xslt30Transformer;
41
using JStylesheetPackage = net.sf.saxon.style.StylesheetPackage;
42
using JXsltPackage = net.sf.saxon.s9api.XsltPackage;
43
using JPackageDetails = net.sf.saxon.trans.packages.PackageDetails;
44
using JPackageLibrary = net.sf.saxon.trans.packages.PackageLibrary;
45
using JVersionedPackageName = net.sf.saxon.trans.packages.VersionedPackageName;
46
using JMap = java.util.Map;
47
using JDotNetOutputStream = net.sf.saxon.dotnet.DotNetOutputStream;
48
using JDestination = net.sf.saxon.s9api.Destination;
49
using javax.xml.transform;
50
using JResultDocumentResolver = net.sf.saxon.lib.ResultDocumentResolver;
51
using System.Runtime.CompilerServices;
52

    
53
namespace Saxon.Api
54
{
55

    
56
    /// <summary>
57
    /// An <c>XsltCompiler</c> object allows XSLT 3.0 stylesheets to be compiled.
58
    /// The compiler holds information that represents the static context
59
    /// for the compilation.
60
    /// </summary>
61
    /// <remarks>
62
    /// <para>To construct an <c>XsltCompiler</c>, use the factory method
63
	/// <c>NewXsltCompiler</c> on the <see cref="Processor"/> object.</para>
64
    /// <para>An <c>XsltCompiler</c> may be used repeatedly to compile multiple
65
    /// queries. Any changes made to the <c>XsltCompiler</c> (that is, to the
66
    /// static context) do not affect queries that have already been compiled.
67
    /// An <c>XsltCompiler</c> may be used concurrently in multiple threads, but
68
    /// it should not then be modified once initialized.</para>
69
    /// </remarks>
70

    
71
    [Serializable]
72
    public class XsltCompiler
73
    {
74
        private Processor processor;
75
        private Uri baseUri;
76
        private ErrorReporterToStaticError errorGatherer;
77
        private ErrorReporter errorReporter;
78
        private IDictionary<QName, XdmValue> variableList = new Dictionary<QName, XdmValue>();
79
        private JXsltCompiler xsltCompiler;
80
        private XmlResolver xmlResolver = null;
81

    
82
        // internal constructor: the public interface is a factory method
83
        // on the Processor object
84

    
85
        internal XsltCompiler(Processor processor)
86
        {
87
            this.processor = processor;
88
            xsltCompiler = processor.JProcessor.newXsltCompiler();
89
            errorGatherer = new ErrorReporterToStaticError(new List<StaticError>());
90
            errorReporter = new ErrorReporter(new List<XmlProcessingError>());
91
            //xsltCompiler.setErrorReporter(errorReporter);
92
            xsltCompiler.setURIResolver(processor.Implementation.getURIResolver());
93
        }
94

    
95
        /// <summary>
96
        /// The base URI of the stylesheet, which forms part of the static context
97
        /// of the stylesheet. This is used for resolving any relative URIs appearing
98
        /// within the stylesheet, for example in <c>xsl:include</c> and <c>xsl:import</c>
99
        /// declarations, in schema locations defined to <c>xsl:import-schema</c>, 
100
        /// or as an argument to the <c>document()</c> or <c>doc()</c> function.
101
        /// </summary>
102
        /// <remarks>
103
        /// This base URI is used only if the input supplied to the <c>Compile</c> method
104
        /// does not provide its own base URI. It is therefore used on the version of the
105
        /// method that supplies input from a <c>Stream</c>. On the version that supplies
106
        /// input from an <c>XmlReader</c>, this base URI is used only if the <c>XmlReader</c>
107
        /// does not have its own base URI.
108
        /// </remarks>
109

    
110

    
111
        public Uri BaseUri
112
        {
113
            get { return baseUri; }
114
            set { baseUri = value; }
115
        }
116

    
117
        /// <summary>
118
        /// Create a collation based on a given <c>CompareInfo</c> and <c>CompareOptions</c>.    
119
        /// </summary>
120
        /// <remarks>
121
        /// In the current and recent releases of Saxon, collations are always defined at the level of a <c>Configuration</c>.
122
        /// Declaring a collation here may therefore have wider effects than intended. It is recommended not to use
123
        /// this method, but to use <see cref="Processor.DeclareCollation(Uri, CompareInfo, CompareOptions)"/> instead.
124
        /// </remarks>
125
        /// <param name="uri">The collation URI to be used within the XPath expression to refer to this collation</param>
126
        /// <param name="compareInfo">The <c>CompareInfo</c>, which determines the language-specific
127
        /// collation rules to be used</param>
128
        /// <param name="options">Options to be used in performing comparisons, for example
129
        /// whether they are to be case-blind and/or accent-blind</param>
130
        /// <param name="isDefault">If true, this collation will be used as the default collation</param>
131

    
132
        [Obsolete("Declare collations globally at the Processor level.")]
133
        public void DeclareCollation(Uri uri, CompareInfo compareInfo, CompareOptions options, Boolean isDefault)
134
        {
135
            JDotNetComparator comparator = new JDotNetComparator(uri.ToString(), compareInfo, options);
136
            processor.JProcessor.getUnderlyingConfiguration().registerCollation(uri.ToString(), comparator);
137
        }
138

    
139
        /// <summary>
140
        /// The name of the default collation used by stylesheets compiled using this <c>XsltCompiler</c>.
141
        /// This must be the name of a collation that is known to the <c>Processor</c>.
142
        /// </summary>
143
        
144
		public String DefaultCollationName
145
        {
146
            get { return xsltCompiler.getDefaultCollation(); }
147
            set { xsltCompiler.declareDefaultCollation(value); }
148
        }
149

    
150
        /// <summary>
151
        /// The <c>Processor</c> from which this <c>XsltCompiler</c> was constructed
152
        /// </summary>
153
        
154
		public Processor Processor
155
        {
156
            get { return processor; }
157
        }
158

    
159
        /// <summary>
160
        /// An <c>XmlResolver</c>, which will be used to resolve URI references while compiling
161
        /// a stylesheet.
162
        /// </summary>
163
        /// <remarks>
164
        /// If no <c>XmlResolver</c> is set for the <c>XsltCompiler</c>, the <c>XmlResolver</c>
165
        /// that is used is the one that was set on the <c>Processor</c> at the time <c>NewXsltCompiler</c>
166
        /// was called.
167
        /// </remarks>
168

    
169
        public XmlResolver XmlResolver
170
        {
171
            get
172
            {
173
                if (xmlResolver == null)
174
                {
175
                    javax.xml.transform.URIResolver resolver = xsltCompiler.getUnderlyingCompilerInfo().getURIResolver();
176
                    if (resolver is JDotNetURIResolver)
177
                    {
178
                        return ((JDotNetURIResolver)resolver).getXmlResolver();
179
                    }
180
                    else
181
                    {
182
                        xmlResolver = new XmlUrlResolver();
183
                        return xmlResolver;
184
                    }
185
                }
186
                else
187
                {
188
                    return xmlResolver;
189
                }
190

    
191
            }
192
            set
193
            {
194
                xmlResolver = value;
195
                xsltCompiler.getUnderlyingCompilerInfo().setURIResolver(new JDotNetURIResolver(xmlResolver));
196
            }
197
        }
198

    
199
        /// <summary>
200
        /// The <c>SchemaAware</c> property determines whether the stylesheet is schema-aware. By default, a stylesheet
201
        /// is schema-aware if it contains one or more <code>xsl:import-schema</code> declarations. This option allows
202
        /// a stylesheet to be marked as schema-aware even if it does not contain such a declaration.
203
        /// </summary>
204
        /// <remarks>
205
        /// <para>If the stylesheet is not schema-aware, then schema-validated input documents will be rejected.</para>
206
        /// <para>The reason for this option is that it is expensive to generate code that can handle typed input
207
        /// documents when they will never arise in practice.</para>
208
        /// <para>The initial setting of this property is false, regardless of whether or not the <c>Processor</c>
209
        /// is schema-aware. Setting this property to true if the processor is not schema-aware will cause an Exception.</para>
210
        /// </remarks>
211

    
212
        public bool SchemaAware
213
        {
214
            get
215
            {
216
                return xsltCompiler.isSchemaAware();
217
            }
218
            set
219
            {
220
                xsltCompiler.setSchemaAware(value);
221
            }
222
        }
223

    
224

    
225
        /// <summary>
226
        /// Indicates whether or not assertions (<c>xsl:assert</c> instructions) are enabled at compile time. 
227
        /// </summary>
228
        /// <remarks>By default assertions are disabled at compile time. If assertions are enabled at compile time, then by
229
        /// default they will also be enabled at run time; but they can be disabled at run time by
230
        /// specific request. At compile time, assertions can be enabled for some packages and
231
        /// disabled for others; at run time, they can only be enabled or disabled globally.</remarks>
232
		/// <returns>true if assertions are enabled at compile time</returns>
233

    
234

    
235
        public bool AssertionsEnabled
236
        {
237
            get
238
            {
239
                return xsltCompiler.isAssertionsEnabled();
240
            }
241
            set
242
            {
243
                xsltCompiler.setAssertionsEnabled(value);
244
            }
245
        }
246

    
247
        /// <summary>
248
        /// The <c>XsltLanguageVersion</c> property determines the version of the XSLT language specification
249
        /// implemented by the compiler. In this Saxon release the value is always "3.0".
250
        /// </summary>
251
        /// <remarks>
252
        /// <para>Getting this property always returns "3.0".</para>
253
        /// <para>Setting this property has no effect.</para>
254
        /// </remarks>
255

    
256
        public string XsltLanguageVersion
257
        {
258
            get
259
            {
260
                return "3.0";
261
            }
262
            set
263
            {}
264
        }
265

    
266
        /// <summary>
267
        /// This property determines whether bytecode is to be generated in the compiled stylesheet.
268
        /// </summary>
269
        /// <remarks>
270
        /// <para>
271
        /// Bytecode generation is enabled by default in Saxon-EE, but can be disabled by clearing this property.
272
        /// In Saxon-HE and Saxon-PE, attempting to set this property to true either has no effect, or causes an error.
273
        /// </para>
274
        /// <para>
275
        /// Setting this property on causes bytecode to be generated for sections of the stylesheet that are
276
        /// executed frequently enough to justify it. It does not force immediate (eager) byte code generation.
277
        /// </para>
278
        /// </remarks>
279
		/// <returns>true if bytecode is to be generated, false if not</returns>
280
        
281
		public bool ByteCodeEnabled {
282
            
283
            get{ return xsltCompiler.getUnderlyingCompilerInfo().isGenerateByteCode(); }
284
            set { xsltCompiler.getUnderlyingCompilerInfo().setGenerateByteCode(value); }
285
        }
286

    
287

    
288

    
289
        /// <summary>
290
        /// List of errors. The caller should supply an empty list before calling Compile;
291
        /// the processor will then populate the list with error information obtained during
292
        /// the compilation. Each error will be included as an object of type <c>StaticError</c>.
293
        /// If no error list is supplied by the caller, error information will be written to
294
        /// an error list allocated by the system, which can be obtained as the value of this property.
295
        /// </summary>
296
        /// <remarks>
297
		/// By supplying a custom <c>List</c> with a user-written <c>add()</c> method, it is possible to
298
        /// intercept error conditions as they occur.
299
        /// </remarks>
300
        [Obsolete("IList<StaticError> ErrorList is deprecated, please use the methods SetErrorList and GetErrorList which hanldes IList<XmlProcessingError>.")]
301
        public IList<StaticError> ErrorList
302
        {
303
            set
304
            {
305
                errorGatherer = new ErrorReporterToStaticError(value);
306
                xsltCompiler.setErrorReporter(errorGatherer);
307
            }
308
            get
309
            {
310
                return errorGatherer.ErrorList;
311
            }
312
        }
313

    
314
        /// <summary>Set the <c>ErrorReporter</c> to be used when validating instance documents as a user defined IErrorReporter.
315
        /// If this property is used then the ErrorList property and SetErrorList method is overriden </summary>
316
        /// <remarks>The <c>IErrorReporter</c> to be used</remarks>
317
        public IErrorReporter ErrorReporter
318
        {
319
            set
320
            {
321
                errorReporter = null;
322
                xsltCompiler.setErrorReporter(new ErrorReporterWrapper(value));
323
            }
324

    
325
        }
326

    
327

    
328
        /// <summary>
329
		/// List of errors. The caller may supply an empty list before calling <c>Compile</c>;
330
        /// the processor will then populate the list with error information obtained during
331
		/// the XSLT compilation. Each error will be included as an object of type <c>XmlProcessingError</c>.
332
        /// If no error list is supplied by the caller, error information will be written to
333
        /// the standard error stream.
334
        /// </summary>
335
        /// <remarks>
336
		/// <para>By supplying a custom <c>List</c> or IErrorReport implementation with a user-written <c>report()</c> method, it is possible to
337
        /// intercept error conditions as they occur.</para>
338
        /// <para>Note that this error list is used only for errors detected during the compilation
339
        /// of the stylesheet. It is not used for errors detected when executing the stylesheet.</para>
340
		/// </remarks>
341
		/// <param name="value">Supplied list.</param>
342
        public void SetErrorList(IList<XmlProcessingError> value)
343
        {
344
            errorReporter = new ErrorReporter(value);
345
            xsltCompiler.setErrorReporter(errorReporter);
346
        }
347

    
348
		/// <summary>
349
		/// Get list of errors as <code>IList&lt;XmlProcessingError&gt;</code>
350
		/// </summary>
351
        public IList<XmlProcessingError> GetErrorList()
352
        {
353
            return errorReporter.ErrorList;
354

    
355
        }
356

    
357

    
358

    
359
        /// <summary>
360
        /// Compile a stylesheet supplied as a Stream.
361
        /// </summary>
362
        /// <example>
363
        /// <code>
364
        /// Stream source = new FileStream("input.xsl", FileMode.Open, FileAccess.Read);
365
        /// XsltExecutable q = compiler.Compile(source);
366
        /// source.Close();
367
        /// </code>
368
        /// </example>
369
        /// <param name="input">A stream containing the source text of the stylesheet</param>
370
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
371
        /// The <c>XsltExecutable</c> may be loaded as many times as required, in the same or a different
372
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
373
        /// once it has been compiled.</returns>
374
        /// <remarks>
375
        /// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
376
        /// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
377
        /// <para>The stylesheet is contained in the part of the input stream between its current
378
        /// position and the end of the stream. It is the caller's responsibility to close the input 
379
        /// stream after use. If the compilation succeeded, then on exit the stream will be 
380
        /// exhausted; if compilation failed, the current position of the stream on exit is
381
        /// undefined.</para>
382
        /// </remarks>
383

    
384
        public XsltExecutable Compile(Stream input)
385
        {
386
            try
387
            {
388
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
389
                if (baseUri != null)
390
                {
391
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
392
                }
393
                XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(ss));
394
                executable.InternalProcessor = processor;
395
                return executable;
396
            }
397
            catch (JSaxonApiException err)
398
            {
399
                throw new StaticError(err);
400
            }
401
        }
402

    
403
		// internal method: Compile a stylesheet supplied as a Stream.
404
		// For example:
405
		// <code>
406
		// Stream source = new FileStream("input.xsl", FileMode.Open, FileAccess.Read);
407
		// XsltExecutable q = compiler.Compile(source);
408
		// source.Close();
409
		// </code>
410
		// <param name="input">A stream containing the source text of the stylesheet</param>
411
		// <param name="theBaseUri">Specify the base URI of the stream</param>
412
		// <param name="closeStream">Flag to indicate if the stream should be closed in the method</param>
413
		// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
414
		// The XsltExecutable may be loaded as many times as required, in the same or a different
415
		// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
416
		// once it has been compiled.</returns>
417
		// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
418
		// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
419
		// <para>The stylesheet is contained in the part of the input stream between its current
420
		// position and the end of the stream. It is the caller's responsibility to close the input 
421
		// stream after use. If the compilation succeeded, then on exit the stream will be 
422
		// exhausted; if compilation failed, the current position of the stream on exit is
423
		// undefined.</para>
424

    
425
        internal XsltExecutable Compile(Stream input, String theBaseUri, bool closeStream)
426
        {
427
            //See bug 2306
428
            try
429
            {
430
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
431
                if (theBaseUri != null)
432
                {
433
                    ss.setSystemId(Uri.EscapeUriString(theBaseUri.ToString()));
434
                }
435
                else
436
                {
437
                    if (baseUri != null)
438
                    {
439
                        ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
440
                    }
441
                }
442
                JXsltExecutable jexecutable =  xsltCompiler.compile(ss);
443
               
444
                if (closeStream)
445
                {
446
                    input.Close();
447
                }
448
                XsltExecutable executable = new XsltExecutable(jexecutable);
449
                executable.InternalProcessor = processor;
450
                return executable;
451
            }
452
            catch (JSaxonApiException err)
453
            {
454
                throw new StaticError(err);
455
            }
456
        }
457

    
458

    
459

    
460
        /// <summary>Compile a library package.</summary>
461
        /// <remarks>
462
        /// <para>The source argument identifies an XML file containing an <c>xsl:package</c> element. Any packages
463
        /// on which this package depends must have been made available to the <c>XsltCompiler</c>
464
        /// by importing them using <see cref="ImportPackage"/>.</para>
465
        /// </remarks>
466
        /// <param name='input'>source identifies an XML document holding the the XSLT package to be compiled</param>
467
        /// <returns>The <c>XsltPackage</c> that results from the compilation. Note that this package
468
        /// is not automatically imported to this <c>XsltCompiler</c>; if the package is required
469
        /// for use in subsequent compilations then it must be explicitly imported.</returns>
470

    
471
        public XsltPackage CompilePackage(Stream input)
472
        {
473
            try
474
            {
475
                JStreamSource ss = new JStreamSource(new JDotNetInputStream(input));
476
                if (baseUri != null)
477
                {
478
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
479
                }
480

    
481
                return new XsltPackage(processor, xsltCompiler.compilePackage(ss));
482
            }
483
            catch (JSaxonApiException err)
484
            {
485
                throw new StaticError(err);
486
            }
487
        }
488

    
489

    
490

    
491

    
492
        /// <summary>Compile a list of packages.</summary>
493
        /// <param name='sources'> the collection of packages to be compiled, in the form of an
494
		/// <c>Iterable</c></param>
495
		/// <returns> the collection of compiled packages, in the form of an <c>Iterable</c></returns> 
496
        [Obsolete("CompilePackages is deprecated, please use configuration to add list of packages.")]
497
        public IList<XsltPackage> CompilePackages(IList<String> sources)
498
        {
499
            JCompilerInfo compilerInfo = xsltCompiler.getUnderlyingCompilerInfo();
500
            JConfiguration config = xsltCompiler.getUnderlyingCompilerInfo().getConfiguration();
501
            JCompilation compilation = new JCompilation(config,compilerInfo);
502
            
503
             java.util.Set sourcesJList = new java.util.HashSet();
504

    
505
            foreach (String sourceStr in sources)
506
            {
507
                sourcesJList.add(new java.io.File(sourceStr));
508

    
509
            }
510

    
511

    
512
            java.lang.Iterable resultJList = null;
513

    
514
            try
515
            {
516
                compilerInfo.setPackageLibrary(new JPackageLibrary(compilerInfo, sourcesJList));
517

    
518
                resultJList =compilerInfo.getPackageLibrary().getPackages();
519

    
520

    
521
            }
522
            catch (JTransformerException ex)
523
            {
524
                throw new StaticError(ex);
525
            }
526
            IList<XsltPackage> result = new List<XsltPackage>();
527
            java.util.Iterator iter = resultJList.iterator();
528

    
529
            for (; iter.hasNext();)
530
            {
531
                JXsltPackage pp = (JXsltPackage)iter.next();
532
                result.Add(new XsltPackage(processor, pp));
533
            }
534

    
535
            return result;
536
        }
537

    
538

    
539

    
540

    
541
        /// <summary>Import a library package. Calling this method makes the supplied package available for reference
542
        /// in the <code>xsl:use-package</code> declaration of subsequent compilations performed using this
543
        /// <code>XsltCompiler</code>.</summary>
544
        /// <param name='thePackage'> the package to be imported</param>
545
        /// <remarks>since 9.6</remarks>
546

    
547
        public void ImportPackage(XsltPackage thePackage)
548
        {
549
            if (thePackage.Processor != this.processor)
550
            {
551
                throw new StaticError(new JTransformerException("The imported package and the XsltCompiler must belong to the same Processor"));
552
            }
553
            GetUnderlyingCompilerInfo().getPackageLibrary().addPackage(thePackage.getUnderlyingPreparedPackage());
554
        }
555

    
556

    
557
        /// <summary>Import a library package. Calling this method makes the supplied package available for reference
558
        /// in the <code>xsl:use-package</code> declaration of subsequent compilations performed using this
559
        /// <code>XsltCompiler</code>.</summary>
560
		/// <param name='thePackage'> the package to be imported</param>
561
		/// <param name='packageName'> name of the package to be imported</param>
562
		/// <param name='version'> version identifier for the package to be imported</param>
563
        /// <remarks>since 9.8</remarks>
564

    
565
        public void ImportPackage(XsltPackage thePackage, string packageName, string version)
566
        {
567
            if (thePackage.Processor != this.processor)
568
            {
569
                throw new StaticError(new JTransformerException("The imported package and the XsltCompiler must belong to the same Processor"));
570
            }
571
            try {
572
                JPackageDetails details = new JPackageDetails();
573
                if (packageName == null) {
574
                    packageName = thePackage.PackageName;
575
                }
576
                if (version == null) {
577
                    version = thePackage.Version;
578
                }
579
                details.nameAndVersion = new JVersionedPackageName(packageName, version);
580
                details.loadedPackage = thePackage.getUnderlyingPreparedPackage();
581
                xsltCompiler.getUnderlyingCompilerInfo().getPackageLibrary().addPackage(details);
582
            } catch (JTransformerException ex) {
583
                throw new StaticError(ex);
584
            }
585
        }
586

    
587

    
588
        /// <summary>
589
		/// Load a compiled package from a file or from a remote location.
590
		/// </summary>
591
		/// <remarks>
592
        /// The supplied URI represents the location of a resource which must have been originally
593
		/// created using <see cref="XsltPackage.Save(Stream)"/>.
594
        /// The result of loading the package is returned as an <code>XsltPackage</code> object.
595
        /// Note that this package is not automatically imported to this <code>XsltCompiler</code>;
596
        /// if the package is required for use in subsequent compilations then it must be explicitly
597
        /// imported.
598
		/// </remarks>
599
        /// <param name="location">the location from which the package is to be loaded, as a URI</param>
600
        /// <returns>the compiled package loaded from the supplied file or remote location</returns>
601

    
602
        public XsltPackage LoadLibraryPackage(Uri location)
603
        {
604
            try
605
            {
606
                JXsltPackage package = xsltCompiler.loadLibraryPackage(new java.net.URI(location.ToString()));
607
                return new XsltPackage(processor, package);
608

    
609
            }
610
            catch (net.sf.saxon.trans.XPathException e)
611
            {
612
                throw new StaticError(e);
613
            }
614

    
615

    
616
        }
617

    
618
        /// <summary>
619
        /// Load a compiled package from a file or from a remote location, with the intent to use this as a complete
620
		/// executable stylesheet, not as a library package.
621
		/// </summary>
622
		/// <remarks>
623
        /// The supplied URI represents the location of a resource which must have been originally
624
		/// created using <see cref="XsltPackage.Save(Stream)"/>.
625
		/// </remarks>
626
        /// <param name="location"> the location from which the package is to be loaded, as a URI</param>
627
        /// <returns>the compiled package loaded from the supplied file or remote location</returns>
628

    
629
        public XsltExecutable LoadExecutablePackage(Uri location)
630
        {
631
            XsltExecutable executable = LoadLibraryPackage(location).Link();
632
            executable.InternalProcessor = processor;
633
            return executable;
634
        }
635

    
636

    
637
        ///	<summary>  
638
		/// Get the underlying <c>CompilerInfo</c> object, which provides more detailed (but less stable) control
639
        /// over some compilation options
640
        /// </summary>
641
		/// <returns> the underlying <c>CompilerInfo</c> object, which holds compilation-time options. The methods on
642
        /// this object are not guaranteed stable from release to release.
643
        /// </returns>
644

    
645
        public JCompilerInfo GetUnderlyingCompilerInfo()
646
        {
647
            return xsltCompiler.getUnderlyingCompilerInfo();
648
        }
649

    
650

    
651
        /// <summary>
652
        /// Externally set the value of a static parameter (new facility in XSLT 3.0) 
653
        /// </summary>
654
        /// <param name="name">The name of the parameter, expressed
655
        /// as a QName. If a parameter of this name has been declared in the
656
        /// stylesheet, the given value will be assigned to the variable. If the
657
        /// variable has not been declared, calling this method has no effect (it is
658
        /// not an error).</param>
659
        /// <param name="value">The value to be given to the parameter.
660
        /// If the parameter declaration defines a required type for the variable, then
661
        /// this value will be converted in the same way as arguments to function calls
662
        /// (for example, numeric promotion is applied).</param>
663

    
664
        public void SetParameter(QName name, XdmValue value)
665
        {
666
            if (value == null)
667
            {
668
                if (variableList.ContainsKey(name))
669
                {
670
                    variableList.Remove(name);
671
                    xsltCompiler.getUnderlyingCompilerInfo().setParameter(name.ToStructuredQName(), null);
672
                }
673
            }
674
            else
675
            {
676
                variableList[name] = value;
677
                xsltCompiler.getUnderlyingCompilerInfo().setParameter(name.ToStructuredQName(), value.value);
678
            }
679
        }
680

    
681

    
682
        /// <summary>
683
        /// Clear the values of all stylesheet parameters previously set using <c>SetParameter(QName, XdmValue)</c>.
684
        /// This resets the parameters to their initial ("undeclared") state
685
        /// </summary>
686
        public void ClearParameters() {
687
            xsltCompiler.clearParameters();
688
        }
689

    
690
        /// <summary>
691
        /// Property to check and set fast compilation. Fast compilation will generally be achieved at the expense of run-time performance
692
        /// and quality of diagnostics. Fast compilation is a good trade-off if (a) the stylesheet is known to be correct,
693
        /// and (b) once compiled, it is only executed once against a document of modest size.
694
		/// </summary>
695
		/// <remarks>
696
        /// <para>Fast compilation may result in static errors going unreported, especially if they occur in code
697
        /// that is never executed.</para>
698
        /// <para><i>The current implementation is equivalent to switching off all optimizations other than just-in-time
699
        /// compilation of template rules. Setting this option, however, indicates an intent rather than a mechanism,
700
        /// and the implementation details may change in future to reflect the intent.</i></para>
701
        /// <para>Set to true to request fast compilation; set to false to revert to the optimization options
702
		/// defined in the Configuration.</para>
703
		/// </remarks>
704

    
705
        public bool FastCompilation {
706

    
707
            set { xsltCompiler.setFastCompilation(value); }
708
            get { return xsltCompiler.isFastCompilation(); }
709
        }
710

    
711

    
712
        [Obsolete("This property has been replaced by FastCompilation.")]
713
        public bool FastCompliation
714
        {
715

    
716
            set { xsltCompiler.setFastCompilation(value); }
717
            get { return xsltCompiler.isFastCompilation(); }
718
        }
719

    
720
        /// <summary>
721
		/// Compile a stylesheet supplied as a <c>TextReader</c>.
722
        /// </summary>
723
        /// <example>
724
        /// <code>
725
        /// String ss = "<![CDATA[<xsl:stylesheet version='2.0'>....</xsl:stylesheet>]]>";
726
        /// TextReader source = new StringReader(ss);
727
        /// XsltExecutable q = compiler.Compile(source);
728
        /// source.Close();
729
        /// </code>
730
        /// </example>
731
        /// <param name="input">A <c>TextReader</c> containing the source text of the stylesheet</param>
732
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
733
		/// The <c>XsltExecutable</c> may be loaded as many times as required, in the same or a different
734
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
735
        /// once it has been compiled.</returns>
736
        /// <remarks>
737
        /// <para>If the stylesheet contains any <c>xsl:include</c> or <c>xsl:import</c> declarations,
738
        /// then the <c>BaseUri</c> property must be set to allow these to be resolved.</para>
739
        /// <para>The stylesheet is contained in the part of the input stream between its current
740
        /// position and the end of the stream. It is the caller's responsibility to close the 
741
        /// <c>TextReader</c> after use. If the compilation succeeded, then on exit the stream will be 
742
        /// exhausted; if compilation failed, the current position of the stream on exit is
743
        /// undefined.</para>
744
        /// </remarks>
745

    
746
        public XsltExecutable Compile(TextReader input)
747
        {
748
            try {
749
                JStreamSource ss = new JStreamSource(new JDotNetReader(input));
750
                if (baseUri != null)
751
                {
752
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
753
                }
754

    
755
                XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(ss));
756
                executable.InternalProcessor = processor;
757
                return executable;
758
            }
759
            catch (JSaxonApiException ex) {
760
                throw new StaticError(ex);
761
            }
762
        }
763

    
764
        /// <summary>
765
        /// Compile a stylesheet, retrieving the source using a URI.
766
        /// </summary>
767
        /// <remarks>
768
        /// The document located via the URI is parsed using the <c>System.Xml</c> parser. This
769
        /// URI is used as the base URI of the stylesheet: the <c>BaseUri</c> property of the
770
        /// <c>Compiler</c> is ignored.
771
        /// </remarks>
772
        /// <param name="uri">The URI identifying the location where the stylesheet document can be
773
        /// found</param>
774
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
775
		/// The <c>XsltExecutable</c> may be run as many times as required, in the same or a different
776
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
777
        /// once it has been compiled.</returns>
778

    
779
        public XsltExecutable Compile(Uri uri)
780
        {
781
            Object obj = XmlResolver.GetEntity(uri, "application/xml", Type.GetType("System.IO.Stream"));
782
            if (obj is Stream)
783
            {
784

    
785
                // See bug issue #2306
786
                XsltExecutable executable = Compile((Stream)obj, uri.ToString(), true);
787
                executable.InternalProcessor = processor;
788
                return executable;
789

    
790
            }
791
            else
792
            {
793
                throw new ArgumentException("Invalid type of result from XmlResolver.GetEntity: " + obj);
794
            }
795
        }
796

    
797
        /// <summary>
798
		/// Compile a stylesheet, delivered using an <c>XmlReader</c>.
799
        /// </summary>
800
        /// <remarks>
801
		/// <para>
802
        /// The <c>XmlReader</c> is responsible for parsing the document; this method builds a tree
803
        /// representation of the document (in an internal Saxon format) and compiles it.
804
        /// The <c>XmlReader</c> will be used as supplied; it is the caller's responsibility to
805
        /// ensure that the settings of the <c>XmlReader</c> are consistent with the requirements
806
        /// of the XSLT specification (for example, that entity references are expanded and whitespace
807
        /// is preserved).
808
		/// </para>
809
		/// <para>
810
        /// If the <c>XmlReader</c> has a <c>BaseUri</c> property, then that property determines
811
        /// the base URI of the stylesheet module, which is used when resolving any <c>xsl:include</c>
812
        /// or <c>xsl:import</c> declarations. If the <c>XmlReader</c> has no <c>BaseUri</c>
813
        /// property, then the <c>BaseUri</c> property of the <c>Compiler</c> is used instead.
814
        /// An <c>ArgumentNullException</c> is thrown if this property has not been supplied.
815
		/// </para>
816
        /// </remarks>
817
        /// <param name="reader">The XmlReader (that is, the XML parser) used to supply the document containing
818
        /// the principal stylesheet module.</param>
819
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
820
        /// The XsltExecutable may be run as many times as required, in the same or a different
821
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
822
        /// once it has been compiled.</returns>
823

    
824

    
825
        public XsltExecutable Compile(XmlReader reader)
826
        {
827
            JDotNetPullProvider pp = new JDotNetPullProvider(reader);
828
            JPipelineConfiguration pipe = processor.Implementation.makePipelineConfiguration();
829
            pp.setPipelineConfiguration(pipe);
830
            // pp = new PullTracer(pp);  /* diagnostics */
831
            JPullSource source = new JPullSource(pp);
832
            String baseu = reader.BaseURI;
833
            if (baseu == null || baseu == String.Empty)
834
            {
835
                // if no baseURI is supplied by the XmlReader, use the one supplied to this Compiler
836
                if (baseUri == null)
837
                {
838
                    throw new ArgumentNullException("BaseUri");
839
                }
840
                baseu = Uri.EscapeUriString(baseUri.ToString());
841
                pp.setBaseURI(baseu);
842
            }
843
            source.setSystemId(baseu);
844
            try {
845

    
846
                XsltExecutable executable =  new XsltExecutable(xsltCompiler.compile(source));
847
                executable.InternalProcessor = processor;
848
                return executable;
849
            }
850
            catch (JSaxonApiException e) {
851
                throw new StaticError(e);
852
            }
853

    
854
            }
855

    
856
        /// <summary>
857
		/// Compile a stylesheet, located at an <c>XdmNode</c>. This may be a document node whose
858
        /// child is an <c>xsl:stylesheet</c> or <c>xsl:transform</c> element, or it may be
859
        /// the <c>xsl:stylesheet</c> or <c>xsl:transform</c> element itself.
860
        /// </summary>
861
        /// <param name="node">The document node or the outermost element node of the document
862
        /// containing the principal stylesheet module.</param>
863
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
864
		/// The <c>XsltExecutable</c> may be run as many times as required, in the same or a different
865
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
866
        /// once it has been compiled.</returns>
867

    
868
        public XsltExecutable Compile(XdmNode node)
869
        {
870
            XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(node.Implementation));
871
            executable.InternalProcessor = processor;
872
            return executable;
873
        }
874

    
875
        /// <summary>Locate and compile a stylesheet identified by an <c>&lt;?xml-stylesheet?&gt;</c>
876
		/// processing instruction within a source document, and that match the given criteria.
877
        /// </summary>
878
        /// <param name="uri">The URI of the source document containing the xml-stylesheet processing instruction.</param>
879
        /// <param name="media">The media attribute to be matched. May be null, in which case the 
880
        /// "application/xml" mime type will be used when fetching the source document from the Uri.</param>
881
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.</returns>
882
		/// <remarks>There are some limitations in the current implementation. Parameters of the xml-stylesheet 
883
		/// instruction other than the media type, are ignored. The
884
        /// <c>href</c> attribute must either reference an embedded stylesheet within the same
885
        /// document or a non-embedded external stylesheet.</remarks>
886

    
887
        public XsltExecutable CompileAssociatedStylesheet(Uri uri, String media)
888
        {
889

    
890
            Object obj = XmlResolver.GetEntity(uri, media == null ? "application/xml" : media, Type.GetType("System.IO.Stream"));
891
            if (obj is Stream)
892
            {
893
                JStreamSource ss = new JStreamSource(new JDotNetInputStream((Stream)obj));
894

    
895
                ss.setSystemId(Uri.EscapeUriString(uri.ToString()));
896
                try
897
                {
898

    
899
                    // See bug issue #2306
900
                    XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(xsltCompiler.getAssociatedStylesheet(ss, media, null, null)));
901
                    executable.InternalProcessor = processor;
902
                    return executable;
903

    
904
                }
905
                catch (JSaxonApiException e)
906
                {
907
                    throw new StaticError(e);
908
                }
909

    
910
            }
911
            else
912
            {
913
                throw new ArgumentException("Invalid type of result from XmlResolver.GetEntity: " + obj);
914

    
915
            }
916
         
917
        }
918

    
919
            /// <summary>Locate and compile a stylesheet identified by an <c>&lt;?xml-stylesheet?&gt;</c>
920
            /// processing instruction within a source document.
921
            /// </summary>
922
            /// <param name="source">The document node of the source document containing the
923
            /// xml-stylesheet processing instruction.</param>
924
            /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.</returns>
925
            /// <remarks>There are some limitations in the current implementation. The media type
926
            /// is ignored, as are the other parameters of the xml-stylesheet instruction. The
927
            /// <c>href</c> attribute must either reference an embedded stylesheet within the same
928
            /// document or a non-embedded external stylesheet.</remarks>
929

    
930
            public XsltExecutable CompileAssociatedStylesheet(XdmNode source)
931
        {
932

    
933

    
934
            // TODO: lift the restrictions
935
            if (source == null || source.NodeKind != XmlNodeType.Document)
936
            {
937
                throw new ArgumentException("Source must be a document node");
938
            }
939
            IEnumerator kids = source.Children(Predicates.IsProcessingInstruction().And(Predicates.HasName("", "xml-stylesheet"))).GetEnumerator();
940
            while (kids.MoveNext())
941
            {
942
                XdmNode n = (XdmNode)kids.Current;
943
                // TODO: check the media type
944
                String href = JProcInstParser.getPseudoAttribute(n.StringValue, "href");
945
                if (href == null)
946
                {
947
                    throw new DynamicError("xml-stylesheet processing instruction has no href attribute");
948
                }
949
                String fragment = null;
950
                int hash = href.LastIndexOf('#');
951
                if (hash == 0)
952
                {
953
                    if (href.Length == 1)
954
                    {
955
                        throw new DynamicError("Relative URI of '#' is invalid");
956
                    }
957
                fragment = href.Substring(1);
958
                JNodeInfo target = ((JTreeInfo)source.value).selectID(fragment, true);
959
                XdmNode targetWrapper = null;
960
                if (target == null)
961
                {
962
                            // There's a problem here because the Microsoft XML parser doesn't
963
                            // report id values, so selectID() will never work. We work around that
964
                            // by looking for an attribute named "id" appearing on an xsl:stylesheet
965
                            // or xsl:transform element
966
                            QName qid = new QName("", "id");
967
                            IEnumerator en = source.EnumerateAxis(XdmAxis.Descendant);
968
                            while (en.MoveNext())
969
                            {
970
                                XdmNode x = (XdmNode)en.Current;
971
                                if (x.NodeKind == XmlNodeType.Element &&
972
                                        x.NodeName.Uri == "http://www.w3.org/1999/XSL/Transform" &&
973
                                        (x.NodeName.LocalName == "stylesheet" || x.NodeName.LocalName == "transform" &&
974
                                        x.GetAttributeValue(qid) == fragment))
975
                                {
976
                                    targetWrapper = x;
977
                                }
978
                            }
979
                        }
980
                        else
981
                        {
982
                            targetWrapper = (XdmNode)XdmValue.Wrap(target);
983
                            targetWrapper.SetProcessor(processor);
984
                        }
985
                        if (targetWrapper == null)
986
                        {
987
                            throw new DynamicError("No element with id='" + fragment + "' found");
988
                        }
989
                        return Compile(targetWrapper);
990
                    }
991
                    else if (hash > 0)
992
                    {
993
                        throw new NotImplementedException("href cannot identify an embedded stylesheet in a different document");
994
                    }
995
                    else
996
                    {
997
                        Uri uri = new Uri(n.BaseUri, href);
998
                        return Compile(uri);
999
                    }
1000
                
1001
            }
1002
            throw new DynamicError("xml-stylesheet processing instruction not found");
1003
        }
1004
    }
1005

    
1006
    /// <summary>
1007
    /// An <c>XsltExecutable</c> represents the compiled form of a stylesheet. To execute the stylesheet,
1008
	/// it must first be loaded to form an <see cref="XsltTransformer"/> or <see cref="Xslt30Transformer"/>.
1009
    /// </summary>
1010
    /// <remarks>
1011
    /// <para>An <c>XsltExecutable</c> is immutable, and therefore thread-safe. It is simplest to
1012
    /// load a new <c>XsltEvaluator</c> each time the stylesheet is to be run. However, the 
1013
    /// <c>XsltEvaluator</c> is serially reusable within a single thread.</para>
1014
    /// <para>An <c>XsltExecutable</c> is created by using one of the <c>Compile</c>
1015
	/// methods on the <see cref="XsltCompiler"/> class.</para>
1016
    /// </remarks>    
1017

    
1018
    [Serializable]
1019
    public class XsltExecutable
1020
    {
1021

    
1022
        // private JPreparedStylesheet pss;
1023
        private Processor processor;
1024
        private JXsltExecutable executable;
1025

    
1026
        // internal constructor
1027

    
1028
        internal XsltExecutable(JXsltExecutable executable)
1029
        {
1030
            //this.processor = proc;
1031
            this.executable = executable;
1032
        }
1033

    
1034
        internal Processor InternalProcessor
1035
        { 
1036
            set { processor = value;}
1037

    
1038
        }
1039

    
1040
        /// <summary>
1041
        /// Get the Processor that was used to create this XsltExecutable
1042
        /// </summary>
1043
        public Processor Processor
1044
        {
1045
            get { return processor; }
1046

    
1047
        }
1048

    
1049
        /// <summary>
1050
        /// Load the stylesheet to prepare it for execution.
1051
        /// </summary>
1052
        /// <returns>
1053
        /// An <c>XsltTransformer</c>. The returned <c>XsltTransformer</c> can be used to
1054
        /// set up the dynamic context for stylesheet evaluation, and to run the stylesheet.
1055
        /// </returns>
1056

    
1057
        public XsltTransformer Load()
1058
        {
1059
           // JXsltController c = pss.newController();
1060
            return new XsltTransformer(executable.load());
1061
        }
1062

    
1063

    
1064

    
1065
        /// <summary>
1066
		/// Load the stylesheet to prepare it for execution. This version of the <c>load()</c> method
1067
        /// creates an <code>Xslt30Transformer</code> which offers interfaces for stylesheet
1068
        /// invocation corresponding to those described in the XSLT 3.0 specification. It can be used
1069
        /// with XSLT 2.0 or XSLT 3.0 stylesheets, and in both cases it offers new XSLT 3.0 functionality such
1070
        /// as the ability to supply parameters to the initial template, or the ability to invoke
1071
        /// stylesheet-defined functions, or the ability to return an arbitrary sequence as a result
1072
        /// without wrapping it in a document node.
1073
        /// </summary>
1074
        /// <returns>
1075
        /// An <c>Xslt30Transformer</c>. The returned <c>Xslt30Transformer</c> can be used to
1076
        /// set up the dynamic context for stylesheet evaluation, and to run the stylesheet.
1077
        /// </returns>
1078

    
1079
        public Xslt30Transformer Load30()
1080
        {
1081
            return new Xslt30Transformer(executable.load30());
1082
        }
1083

    
1084
        /// <summary>
1085
        /// Output an XML representation of the compiled code of the stylesheet, for purposes of 
1086
        /// diagnostics and instrumentation.
1087
        /// </summary>
1088
        /// <param name="destination">The destination for the diagnostic output</param>
1089

    
1090
        public void Explain(XmlDestination destination)
1091
        {
1092
            executable.explain(destination.GetUnderlyingDestination());
1093
        }
1094

    
1095
        /// <summary>
1096
        /// Escape hatch to the underlying Java implementation object.
1097
        /// </summary>
1098

    
1099
        public JXsltExecutable Implementation
1100
        {
1101
            get
1102
            {
1103
                return executable;
1104
            }
1105
        }
1106

    
1107
        /// <summary>
1108
        /// Get the whitespace stripping policy defined by this stylesheet, that is, the policy
1109
        /// defined by the <c>xsl:strip-space</c> and <c>xsl:preserve-space</c> elements in the stylesheet.
1110
        /// </summary>
1111
        /// <returns> a newly constructed <c>WhitespacePolicy</c> based on the declarations in this
1112
        /// stylesheet. This policy can be used as input to a <see cref="DocumentBuilder"/>.</returns>
1113
        
1114
        public WhitespacePolicy getWhitespaceStrippingPolicy() {
1115
            return new WhitespacePolicy(executable);
1116
        }
1117

    
1118

    
1119
        /// <summary>
1120
        /// Get the names of the <c>xsl:param</c> elements defined in this stylesheet, with details
1121
        /// of each parameter including its required type, and whether it is required or optional.
1122
        /// </summary>
1123
        /// <returns>
1124
		/// a <c>Dictionary</c> whose keys are the names of global parameters in the stylesheet,
1125
		/// and whose values are <see cref="Saxon.Api.XsltExecutable+ParameterDetails"/> objects giving information about the
1126
        /// corresponding parameter.
1127
        /// </returns>
1128
        public Dictionary<QName, ParameterDetails> GetGlobalParameters()
1129
        {
1130
            java.util.HashMap globals = executable.getGlobalParameters();
1131
            Dictionary<QName, ParameterDetails> params1 = new Dictionary<QName, ParameterDetails>();
1132
            int count = globals.size();
1133
            object[] names = globals.keySet().toArray();
1134
            for (int i = 0; i < count; i++) {
1135
                JXsltExecutable.ParameterDetails details = (JXsltExecutable.ParameterDetails)globals.get(names[i]);
1136
                XdmSequenceType sType = XdmSequenceType.FromSequenceType(details.getUnderlyingDeclaredType());
1137
                sType.itemType.SetJXdmItemType(details.getDeclaredItemType());
1138
                params1.Add(new QName((net.sf.saxon.s9api.QName)names[i]), new ParameterDetails(sType, false));
1139

    
1140
            }
1141
            return params1;
1142
        }
1143

    
1144
        /// <summary>
1145
        /// Information about a global parameter to a stylesheet.
1146
        /// </summary>
1147

    
1148
        public class ParameterDetails
1149
        {
1150
            private XdmSequenceType type;
1151
            private bool isRequired;
1152

    
1153
            /// <summary>
1154
            /// Create parameter details.
1155
            /// </summary>
1156
            /// <param name="type">The declared type of the parameter.</param>
1157
            /// <param name="isRequired">Indicates whether the parameter is required or optional.</param>
1158
            
1159
            public ParameterDetails(XdmSequenceType type, bool isRequired)
1160
            {
1161
                this.type = type;
1162
                this.isRequired = isRequired;
1163
            }
1164

    
1165
            /// <summary>
1166
            /// Gets the declared item type of the parameter.
1167
            /// </summary>
1168
            /// <returns>The type defined in the <code>as</code> attribute of the <code>xsl:param</code> element,
1169
            /// without its occurrence indicator</returns>
1170
            public XdmItemType GetDeclaredItemType()
1171
            {
1172
                return type.itemType;
1173
            }
1174

    
1175

    
1176
            /// <summary>
1177
            /// Gets the declared cardinality of the parameter.
1178
            /// </summary>
1179
            /// <returns>The occurrence indicator from the type appearing in the <code>as</code> attribute
1180
            /// of the <code>xsl:param</code> element</returns>
1181

    
1182
            public char GetDeclaredCardinality()
1183
            {
1184
                return type.occurrenceIn;
1185
            }
1186

    
1187
            /// <summary>
1188
            /// Gets the underlying declared type of the parameter.
1189
            /// </summary>
1190
            /// <returns>The underlying declared type.</returns>
1191

    
1192
            public XdmSequenceType GetUnderlyingDeclaredType()
1193
            {
1194
                return type;
1195
            }
1196

    
1197

    
1198
            /// <summary>
1199
            /// Ask whether the parameter is required (mandatory) or optional
1200
            /// </summary>
1201
            /// <returns><c>true</c> if the parameter is mandatory (<code>required="yes"</code>), false
1202
            /// if it is optional.</returns>
1203

    
1204
            public bool IsRequired
1205
            {
1206
                set { this.isRequired = value; }
1207
                get { return this.isRequired; }
1208

    
1209
            }
1210
        }
1211

    
1212

    
1213

    
1214

    
1215
    }
1216

    
1217

    
1218
    /// <summary inherits="XdmDestination">
1219
    /// An <c>XsltTransformer</c> represents a compiled and loaded stylesheet ready for execution.
1220
    /// The <c>XsltTransformer</c> holds details of the dynamic evaluation context for the stylesheet.
1221
    /// </summary>
1222
    /// <remarks>
1223
    /// <para>An <c>XsltTransformer</c> must not be used concurrently in multiple threads. It is safe,
1224
    /// however, to reuse the object within a single thread to run the same stylesheet several times.
1225
    /// Running the stylesheet does not change the context that has been established.</para>
1226
    /// <para>An <c>XsltTransformer</c> is always constructed by running the <c>Load</c> method of
1227
    /// an <c>XsltExecutable</c>.</para>
1228
	/// <para>The <see cref="Xslt30Transformer"/> class provides invocation options that are more closely aligned
1229
    /// with the XSLT 3.0 specification, for example streamed evaluation. However, both <c>XsltTransformer</c> 
1230
	/// and <c>Xslt30Transformer</c> can be used irrespective of the XSLT language version used in the stylesheet.</para>
1231
    /// </remarks>
1232

    
1233
    [Serializable]
1234
    public class XsltTransformer : XmlDestination
1235
    {
1236

    
1237
        /* private JXsltController controller;
1238
      
1239
         private JStreamSource streamSource;
1240
         private GlobalParameterSet globalParameters;
1241
         private bool baseOutputUriWasSet = false;*/
1242
        private XmlDestination xmlDestination;
1243
        private StandardLogger traceFunctionDestination;
1244
        private IMessageListener messageListener;
1245
        private IMessageListener2 messageListener2;
1246
        private IResultDocumentHandler resultDocumentHandler;
1247
        private QName initialTemplateName;
1248
        private XdmNode initialContextNode;
1249
        private JXsltTransformer transformer;
1250

    
1251
        // internal constructor
1252

    
1253
        internal XsltTransformer(JXsltTransformer transformer)
1254
        {
1255
            this.transformer = transformer;
1256
        }
1257

    
1258
        /// <summary>
1259
        /// The global context item for the stylesheet, as a node.
1260
        /// </summary>
1261
        /// <remarks><para>Although XSLT 3.0 allows the global context item to be any item,
1262
        /// this interface only allows it to be a node.
1263
        /// Most commonly it will be a document node, which might be constructed
1264
        /// using the <c>Build</c> method of the <c>DocumentBuilder</c> object.</para>
1265
        /// <para>Note that this can be inefficient if the stylesheet uses <c>xsl:strip-space</c>
1266
        /// to strip whitespace, or <c>input-type-annotations="strip"</c> to remove type
1267
        /// annotations, since this will result in the transformation operating on a virtual document
1268
        /// implemented as a view or wrapper of the supplied document.</para>
1269
        /// </remarks>
1270

    
1271
        public XdmNode InitialContextNode
1272
        {
1273
            get {
1274
                JNodeInfo node = transformer.getInitialContextNode().getUnderlyingNode();
1275
                return node == null ? null : ((XdmNode)XdmValue.Wrap(node)); }
1276
            set { transformer.setInitialContextNode(value == null ? null : (net.sf.saxon.s9api.XdmNode)XdmValue.FromGroundedValueToJXdmValue(value.value)); }
1277
        }
1278

    
1279
        /// <summary>
1280
        /// Supply the principal input document for the transformation in the form of a stream.
1281
        /// </summary>
1282
        /// <remarks>
1283
        /// <para>If this method is used, the <c>InitialContextNode</c> is ignored.</para>
1284
        /// <para>The supplied stream will be consumed by the <c>Run()</c> method.
1285
        /// Closing the input stream after use is the client's responsibility.</para>
1286
        /// <para>A base URI must be supplied in all cases. It is used to resolve relative
1287
        /// URI references appearing within the input document.</para>
1288
        /// <para>Schema validation is applied to the input document according to the value of
1289
        /// the <c>SchemaValidationMode</c> property.</para>
1290
        /// <para>Whitespace stripping is applied according to the value of the
1291
        /// <c>xsl:strip-space</c> and <c>xsl:preserve-space</c> declarations in the stylesheet.</para>
1292
        /// </remarks>
1293
        /// <param name="input">
1294
        /// The stream containing the source code of the principal input document to the transformation. The document
1295
        /// node at the root of this document will be the global context item for the transformation.
1296
        /// </param>
1297
        /// <param name="baseUri">
1298
        /// The base URI of the principal input document. This is used for example by the <c>document()</c>
1299
        /// function if the document contains links to other documents in the form of relative URIs.</param>
1300

    
1301
        public void SetInputStream(Stream input, Uri baseUri)
1302
        {
1303
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
1304
            transformer.setSource(streamSource);
1305
        }
1306

    
1307
        /// <summary>
1308
		/// The initial mode for the stylesheet. This is either a <c>QName</c>, for a 
1309
        /// specific mode, or null, for the default mode.
1310
        /// </summary>
1311
        /// <remarks>
1312
        /// The default mode will usually be the unnamed mode, but if the stylesheet declares a
1313
        /// named mode as the default mode, then supplying null as the <c>InitialMode</c> invokes this default.
1314
        /// </remarks>
1315

    
1316
        public QName InitialMode
1317
        {
1318
            get
1319
            {
1320
                net.sf.saxon.s9api.QName mode = transformer.getInitialMode();
1321
                if (mode == null)
1322
                {
1323
                    return null;
1324
                }
1325

    
1326
                return QName.FromClarkName(mode.getClarkName());
1327
            }
1328
            set
1329
            {
1330
               transformer.setInitialMode(value == null ? null : net.sf.saxon.s9api.QName.fromEQName(value.EQName));
1331
            }
1332
        }
1333

    
1334

    
1335
        /// <summary>
1336
		/// The initial template for the stylesheet. This is either a <c>QName</c>, for a 
1337
        /// named template, or null, if no initial template has been set.
1338
        /// </summary>
1339
        /// <remarks>
1340
        /// If the stylesheet is to be invoked by calling the template named <c>xsl:initial-template</c>,
1341
		/// then the <c>InitialTemplate</c> property should be set to this <c>QName</c> explicitly.
1342
        /// </remarks>
1343
        /// <exception cref="DynamicError">Setting this property to the name of a template
1344
		/// that does not exist in the stylesheet throws a <c>DynamicError</c> with error 
1345
        /// code XTDE0040. Setting it to the name of a template that has template
1346
		/// parameters throws a <c>DynamicError</c> with error code XTDE0060.</exception>
1347

    
1348
        public QName InitialTemplate
1349
        {
1350
            get
1351
            {
1352
                return initialTemplateName;
1353
            }
1354
            set
1355
            {
1356
                initialTemplateName = value;
1357
                transformer.setInitialTemplate(initialTemplateName.UnderlyingQName());
1358
            }
1359
        }
1360

    
1361
        /// <summary>
1362
        /// The base output URI, which acts as the base URI for resolving the <c>href</c>
1363
        /// attribute of <c>xsl:result-document</c>.
1364
        /// </summary>
1365

    
1366
        public Uri BaseOutputUri
1367
        {
1368
            get
1369
            {
1370
                return new Uri(transformer.getBaseOutputURI());
1371
            }
1372
            set
1373
            {
1374
                transformer.setBaseOutputURI(value.ToString());
1375
            }
1376
        }
1377

    
1378

    
1379
        /// <summary>
1380
        /// The <c>SchemaValidationMode</c> to be used in this transformation, especially for documents
1381
        /// loaded using the <c>doc()</c>, <c>document()</c>, or <c>collection()</c> functions.
1382
        /// </summary>
1383

    
1384
        public SchemaValidationMode SchemaValidationMode
1385
        {
1386
            get
1387
            {
1388
                switch (transformer.getUnderlyingController().getSchemaValidationMode())
1389
                {
1390
                    case JValidation.STRICT:
1391
                        return SchemaValidationMode.Strict;
1392
                    case JValidation.LAX:
1393
                        return SchemaValidationMode.Lax;
1394
                    case JValidation.STRIP:
1395
                        return SchemaValidationMode.None;
1396
                    case JValidation.PRESERVE:
1397
                        return SchemaValidationMode.Preserve;
1398
                    case JValidation.DEFAULT:
1399
                    default:
1400
                        return SchemaValidationMode.Unspecified;
1401
                }
1402
            }
1403

    
1404
            set
1405
            {
1406
                switch (value)
1407
                {
1408
                    case SchemaValidationMode.Strict:
1409
                        transformer.setSchemaValidationMode(JValidationMode.STRICT);
1410
                        break;
1411
                    case SchemaValidationMode.Lax:
1412
                        transformer.setSchemaValidationMode(JValidationMode.LAX);
1413
                        break;
1414
                    case SchemaValidationMode.None:
1415
                        transformer.setSchemaValidationMode(JValidationMode.STRIP);
1416
                        break;
1417
                    case SchemaValidationMode.Preserve:
1418
                        transformer.setSchemaValidationMode(JValidationMode.PRESERVE);
1419
                        break;
1420
                    case SchemaValidationMode.Unspecified:
1421
                    default:
1422
                        transformer.setSchemaValidationMode(JValidationMode.DEFAULT);
1423
                        break;
1424
                }
1425
            }
1426
        }
1427

    
1428

    
1429

    
1430

    
1431

    
1432
        /// <summary>
1433
        /// The <c>XmlResolver</c> to be used at run-time to resolve and dereference URIs
1434
        /// supplied to the <c>doc()</c> and <c>document()</c> functions.
1435
        /// </summary>
1436

    
1437
        public XmlResolver InputXmlResolver
1438
        {
1439
            get
1440
            {
1441
                return ((JDotNetURIResolver)transformer.getURIResolver()).getXmlResolver();
1442
            }
1443
            set
1444
            {
1445
                transformer.setURIResolver(new JDotNetURIResolver(value));
1446
            }
1447
        }
1448

    
1449
        /// <summary>
1450
        /// The <c>IResultDocumentHandler</c> to be used at run-time to process the output
1451
        /// produced by any <c>xsl:result-document</c> instruction with an <c>href</c>
1452
        /// attribute.
1453
        /// </summary>
1454
        /// <remarks>
1455
        /// In the absence of a user-supplied result document handler, the <c>href</c>
1456
        /// attribute of the <c>xsl:result-document</c> instruction must be a valid relative
1457
        /// URI, which is resolved against the value of the <c>BaseOutputUri</c> property,
1458
        /// and the resulting absolute URI must identify a writable resource (typically
1459
        /// a file in filestore, using the <c>file:</c> URI scheme).
1460
        /// </remarks>
1461

    
1462
        public IResultDocumentHandler ResultDocumentHandler
1463
        {
1464
            get
1465
            {
1466
                return resultDocumentHandler;
1467
            }
1468
            set
1469
            {
1470
                resultDocumentHandler = value;
1471
                transformer.getUnderlyingController().setResultDocumentResolver(new ResultDocumentHandlerWrapper(value, transformer.getUnderlyingController().makePipelineConfiguration()));
1472
            }
1473
        }
1474

    
1475
        /// <summary>
1476
		/// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
1477
		/// </summary>
1478
		/// <remarks> 
1479
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
1480
        /// the processor will then invoke the listener once for each message generated during
1481
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
1482
        /// representing a document node.</para>
1483
        /// <para>If no message listener is supplied by the caller, message information will be written to
1484
        /// the standard error stream.</para>
1485
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
1486
        /// on the message object will usually generate an acceptable representation of the
1487
        /// message.</para>
1488
		/// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
1489
        /// the message is first notified using this interface, and then an exception is thrown
1490
        /// which terminates the transformation.</para>
1491
        /// </remarks>
1492

    
1493
        public IMessageListener MessageListener
1494
        {
1495
            set
1496
            {
1497
                messageListener = value;
1498
                transformer.setMessageListener(new MessageListenerProxy(value));
1499
            }
1500
            get
1501
            {
1502
                return messageListener;
1503
            }
1504
        }
1505

    
1506

    
1507

    
1508
        /// <summary>
1509
        /// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
1510
        /// </summary>
1511
        /// <remarks> 
1512
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
1513
        /// the processor will then invoke the listener once for each message generated during
1514
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
1515
        /// representing a document node.</para>
1516
        /// <para>If no message listener is supplied by the caller, message information will be written to
1517
        /// the standard error stream.</para>
1518
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
1519
        /// on the message object will usually generate an acceptable representation of the
1520
        /// message.</para>
1521
        /// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
1522
        /// the message is first notified using this interface, and then an exception is thrown
1523
        /// which terminates the transformation.</para>
1524
        /// <para>The <c>MessageListener2</c> property interface differs from the <c>MessageListener</c>
1525
        /// in allowing the error code supplied to xsl:message to be notified</para>
1526
        /// </remarks>
1527

    
1528
        public IMessageListener2 MessageListener2
1529
        {
1530
            set
1531
            {
1532
                messageListener2 = value;
1533
                transformer.setMessageListener(new MessageListenerProxy2(value));
1534
            }
1535
            get
1536
            {
1537
                return messageListener2;
1538
            }
1539
        }
1540

    
1541
        /// <summary>
1542
        /// Destination for output of messages using the <c>trace()</c> function.
1543
        /// </summary>
1544
		/// <remarks> 
1545
		/// <para>If no message listener is supplied by the caller, message information will be written to
1546
		/// the standard error stream.</para>
1547
        /// <para>The supplied destination is ignored if a <c>TraceListener</c> is in use.</para>
1548
        /// </remarks>
1549

    
1550
        public StandardLogger TraceFunctionDestination
1551
        {
1552
            set
1553
            {
1554
                traceFunctionDestination = value;
1555
                transformer.setTraceFunctionDestination(value);
1556
            }
1557
            get
1558
            {
1559
                return traceFunctionDestination;
1560
            }
1561
        }
1562

    
1563

    
1564

    
1565
        /// <summary>
1566
        /// Set the value of a stylesheet parameter.
1567
        /// </summary>
1568
        /// <param name="name">The name of the parameter, expressed
1569
        /// as a QName. If a parameter of this name has been declared in the
1570
        /// stylesheet, the given value will be assigned to the variable. If the
1571
        /// variable has not been declared, calling this method has no effect (it is
1572
        /// not an error).</param>
1573
        /// <param name="value">The value to be given to the parameter.
1574
        /// If the parameter declaration defines a required type for the variable, then
1575
        /// this value will be converted in the same way as arguments to function calls
1576
        /// (for example, numeric promotion is applied).</param>
1577

    
1578
        public void SetParameter(QName name, XdmValue value)
1579
        {
1580
            transformer.setParameter(net.sf.saxon.s9api.QName.fromEQName(name.EQName), net.sf.saxon.s9api.XdmValue.wrap(value.value));
1581
        }
1582

    
1583
        public JDestination GetUnderlyingDestination() {
1584
            return transformer;
1585
        }
1586

    
1587

    
1588

    
1589
        /// <summary>
1590
		/// The destination for the result of the transformation. The class <c>XmlDestination</c> is an abstraction 
1591
        /// that allows a number of different kinds of destination to be specified.
1592
        /// </summary>
1593
        /// <remarks>
1594
        /// <para>The Destination can be used to chain transformations into a pipeline, by using one
1595
        /// <c>XsltTransformer</c> as the destination of another.</para>
1596
        /// </remarks>
1597

    
1598
        public XmlDestination Destination
1599
        {
1600
            get
1601
            {
1602
                return this.xmlDestination;
1603
            }
1604
            set
1605
            {
1606
                this.xmlDestination = value;
1607
                transformer.setDestination(value.GetUnderlyingDestination());
1608
            }
1609

    
1610
        }
1611

    
1612

    
1613
        /// <summary>
1614
		/// Close the <c>Destination</c>, releasing any resources that need to be released.
1615
        /// </summary>
1616
        /// <remarks>
1617
        /// This method is called by the system on completion of a query or transformation.
1618
		/// Some kinds of <c>Destination</c> may need to close an output stream, others might
1619
        /// not need to do anything. The default implementation does nothing.
1620
        /// </remarks>
1621

    
1622
        public void Close()
1623
        {
1624
            transformer.close();
1625

    
1626
        }
1627

    
1628
		// internal method
1629

    
1630
        internal JReceiver GetDestinationReceiver(XmlDestination destination)
1631
        {
1632

    
1633
            JController controller = transformer.getUnderlyingController();
1634
                JPipelineConfiguration pipe = controller.getConfiguration().makePipelineConfiguration();
1635
                JReceiver r = destination.GetUnderlyingDestination().getReceiver(pipe, controller.getExecutable().getPrimarySerializationProperties());
1636
                pipe.setController(controller);
1637
                return r;
1638
            //}
1639
        }
1640

    
1641
        /// <summary>
1642
        /// Run the transformation, sending the result to a specified destination.
1643
        /// </summary>
1644
        /// <param name="destination">
1645
        /// The destination for the results of the stylesheet. The class <c>XmlDestination</c>
1646
        /// is an abstraction that allows a number of different kinds of destination
1647
        /// to be specified.
1648
        /// </param>
1649
		/// <exception cref="DynamicError">Throws a <c>DynamicError</c> if the transformation
1650
        /// fails.</exception>
1651

    
1652
        public void Run(XmlDestination destination)
1653
        {
1654
            if (destination == null)
1655
            {
1656
                throw new DynamicError("Destination is null");
1657
            }
1658
           
1659
            try
1660
            {
1661
                transformer.setDestination(destination.GetUnderlyingDestination());
1662
                transformer.transform() ;
1663
               
1664
            }
1665
            catch (JSaxonApiException err)
1666
            {
1667
                throw new DynamicError(err);
1668
            }
1669
        }
1670

    
1671
        /*internal void applyTemplatesToSource(JStreamSource streamSource, JReceiver outi){
1672

    
1673
           
1674
            if (controller.getInitialMode().isDeclaredStreamable()) {
1675
                controller.applyStreamingTemplates(streamSource, outi);
1676
            }
1677
        } */
1678

    
1679
        /// <summary>
1680
        /// Escape hatch to the underlying Java implementation
1681
        /// </summary>
1682

    
1683
        public JController Implementation
1684
        {
1685
            get { return transformer.getUnderlyingController(); }
1686
        }
1687

    
1688

    
1689
    }
1690

    
1691
    /// <summary>
1692
	/// <c>RecoveryPolicy</c> is an enumeration of the different actions that can be taken when a "recoverable error" occurs.
1693
    /// </summary>  
1694

    
1695
    public enum RecoveryPolicy
1696
    {
1697
        /// <summary>
1698
        /// Ignore the error, take the recovery action, do not produce any message
1699
        /// </summary>
1700
        RecoverSilently,
1701

    
1702
        /// <summary>
1703
        /// Take the recovery action after outputting a warning message
1704
        /// </summary>
1705
        RecoverWithWarnings,
1706

    
1707
        /// <summary>
1708
        /// Treat the error as fatal
1709
        /// </summary>
1710
        DoNotRecover
1711

    
1712
    }
1713

    
1714

    
1715

    
1716
    /// <summary>An <c>IResultDocumentHandler</c> can be nominated to handle output
1717
    /// produced by the <c>xsl:result-document</c> instruction in an XSLT stylesheet.
1718
    /// </summary>
1719
    /// <remarks>
1720
    /// <para>This interface affects any <c>xsl:result-document</c> instruction
1721
    /// executed by the stylesheet, provided that it has an <c>href</c> attribute.</para> 
1722
    /// <para>If no <c>IResultDocumentHandler</c> is nominated (in the
1723
    /// <c>IResultDocumentHandler</c> property of the <c>XsltTransformer</c>), the output
1724
    /// of <code>xsl:result-document</code> is serialized, and is written to the file
1725
    /// or other resource identified by the URI in the <c>href</c> attribute, resolved
1726
    /// (if it is relative) against the URI supplied in the <c>BaseOutputUri</c> property
1727
    /// of the <c>XsltTransformer</c>.</para>
1728
    /// <para>If an <c>IResultDocumentHandler</c> is nominated, however, its
1729
    /// <c>HandleResultDocument</c> method will be called whenever an <c>xsl:result-document</c>
1730
    /// instruction with an <c>href</c> attribute is evaluated, and the generated result tree
1731
    /// will be passed to the <c>XmlDestination</c> returned by that method.</para> 
1732
    /// </remarks>
1733

    
1734
    public interface IResultDocumentHandler
1735
    {
1736

    
1737
        /// <summary> Handle output produced by the <c>xsl:result-document</c>
1738
        /// instruction in an XSLT stylesheet. This method is called by the XSLT processor
1739
        /// when an <c>xsl:result-document</c> with an <c>href</c> attribute is evaluated.
1740
        /// </summary>
1741
        /// <param name="href">An absolute or relative URI. This will be the effective value of the 
1742
        /// <c>href</c> attribute of the <c>xsl:result-document</c> in the stylesheet.</param>
1743
        /// <param name="baseUri">The base URI that should be used for resolving the value of
1744
        /// <c>href</c> if it is relative. This will always be the value of the <c>BaseOutputUri</c>
1745
        /// property of the <c>XsltTransformer</c>.</param>
1746
        /// <returns>An <c>XmlDestination</c> to handle the result tree produced by the
1747
        /// <c>xsl:result-document</c> instruction. The <c>Close</c> method of the returned
1748
        /// <c>XmlDestination</c> will be called when the output is complete.</returns>
1749
        /// <remarks>
1750
        /// <para>The XSLT processor will ensure that the stylesheet cannot create
1751
        /// two distinct result documents which are sent to the same URI. It is the responsibility
1752
        /// of the <c>IResultDocumentHandler</c> to ensure that two distinct result documents are
1753
        /// not sent to the same <c>XmlDestination</c>. Failure to observe this rule can result
1754
        /// in output streams being incorrectly closed.
1755
        /// </para>
1756
        /// <para>Note that more than one result document can be open at the same time,
1757
        /// and that the order of opening, writing, and closing result documents chosen
1758
        /// by the processor does not necessarily bear any direct resemblance to the way
1759
        /// that the XSLT source code is written.</para></remarks>
1760
        /**public**/
1761
        XmlDestination HandleResultDocument(string href, Uri baseUri);
1762

    
1763
    }
1764

    
1765
    ///<summary>Internal wrapper class for <c>IResultDocumentHandler</c></summary>
1766
    internal class ResultDocumentHandlerWrapper : JResultDocumentResolver
1767
    {
1768

    
1769
        private IResultDocumentHandler handler;
1770
        private ArrayList resultList = new ArrayList();
1771
        private ArrayList destinationList = new ArrayList();
1772
        private JPipelineConfiguration pipe;
1773

    
1774
        /// <summary>
1775
        /// Initializes a new instance of the <see cref="Saxon.Api.ResultDocumentHandlerWrapper"/> class.
1776
        /// </summary>
1777
        /// <param name="handler">Handler.</param>
1778
        /// <param name="pipe">Pipe.</param>
1779
        public ResultDocumentHandlerWrapper(IResultDocumentHandler handler, JPipelineConfiguration pipe)
1780
        {
1781
            this.handler = handler;
1782
            this.pipe = pipe;
1783
        }
1784

    
1785

    
1786

    
1787

    
1788
        /// <summary>
1789
        /// Close the specified result.
1790
        /// </summary>
1791
        /// <param name="result">Result.</param>
1792
        public void close(JResult result)
1793
        {
1794
            for (int i = 0; i < resultList.Count; i++)
1795
            {
1796
                if (Object.ReferenceEquals(resultList[i], result))
1797
                {
1798
                    ((XmlDestination)destinationList[i]).GetUnderlyingDestination().close();
1799
                    resultList.RemoveAt(i);
1800
                    destinationList.RemoveAt(i);
1801
                    return;
1802
                }
1803
            }
1804
        }
1805

    
1806
        /// <summary>
1807
        /// Resolve the specified href and baseString.
1808
        /// </summary>
1809
        /// <param name="href">Href.</param>
1810
        /// <param name="baseString">Base string.</param>
1811
        public JReceiver resolve(net.sf.saxon.expr.XPathContext xpc, string href, string baseString, net.sf.saxon.serialize.SerializationProperties sp)
1812
        {
1813
            Uri baseUri;
1814
            try
1815
            {
1816
                baseUri = new Uri(baseString);
1817
            }
1818
            catch (System.UriFormatException err)
1819
            {
1820
                throw new JTransformerException("Invalid base output URI " + baseString, err);
1821
            }
1822
            XmlDestination destination = handler.HandleResultDocument(href, baseUri);
1823
            JReceiver result = destination.GetUnderlyingDestination().getReceiver(pipe, sp);
1824
            resultList.Add(result);
1825
            destinationList.Add(destination);
1826
            return result;
1827
        }
1828
    }
1829

    
1830
    /// <summary>An <c>IMessageListener</c> can be nominated to handle output
1831
    /// produced by the <c>xsl:message</c> instruction in an XSLT stylesheet.
1832
    /// </summary>
1833
    /// <remarks>
1834
    /// <para>This interface affects any <c>xsl:message</c> instruction
1835
    /// executed by the stylesheet.</para> 
1836
    /// <para>If no <c>IMessageListener</c> is nominated (in the
1837
    /// <c>MessageListener</c> property of the <c>XsltTransformer</c>), the output
1838
    /// of <code>xsl:message</code> is serialized, and is written to standard error
1839
    /// output stream.</para>
1840
    /// <para>If an <c>IMessageListener</c> is nominated, however, its
1841
    /// <c>Message</c> method will be called whenever an <c>xsl:message</c>
1842
    /// instruction is evaluated.</para> 
1843
    /// </remarks>
1844

    
1845
    public interface IMessageListener
1846
    {
1847

    
1848
        /// <summary>Handle the output of an <c>xsl:message</c> instruction
1849
        /// in the stylesheet
1850
        /// </summary>
1851
        /// <param name="content">a document node representing the message content. Note the putput of <c>xsl:message</c>
1852
        /// is always an XML document node. It can be flattened to obtain the stringvalue if required by calling
1853
        /// <c>GetStringValue()</c></param>
1854
        /// <param name="terminate">Set to true if <c>terminate ='yes'</c> was specified or to false otherwise</param>
1855
        /// <param name="location">an object that contains the location of the <c>xsl:message</c> This provides access to the URI of the stylesheet
1856
        /// module and the line number of the <c>xsl:message</c></param>
1857

    
1858
        /**public**/
1859
        void Message(XdmNode content, bool terminate, IXmlLocation location);
1860

    
1861
    }
1862

    
1863

    
1864

    
1865
    /// <summary>An <c>IMessageListener</c> can be nominated to handle output
1866
    /// produced by the <c>xsl:message</c> instruction in an XSLT stylesheet.
1867
    /// </summary>
1868
    /// <remarks>
1869
    /// <para>This interface affects any <c>xsl:message</c> instruction
1870
    /// executed by the stylesheet.</para> 
1871
    /// <para>If no <c>IMessageListener</c> is nominated (in the
1872
    /// <c>MessageListener</c> property of the <c>XsltTransformer</c>), the output
1873
    /// of <code>xsl:message</code> is serialized, and is written to standard error
1874
    /// output stream.</para>
1875
    /// <para>If an <c>IMessageListener</c> is nominated, however, its
1876
    /// <c>Message</c> method will be called whenever an <c>xsl:message</c>
1877
    /// instruction is evaluated.</para> 
1878
    /// <para>The <c>MessageListener2</c> interface differs from <c>MessageListener</c>
1879
    /// in allowing the error code supplied to <c>xsl:message</c> to be made available.</para>
1880
    /// </remarks>
1881

    
1882
    public interface IMessageListener2
1883
    {
1884

    
1885
        /// <summary>Handle the output of an <c>xsl:message</c> instruction
1886
        /// in the stylesheet
1887
        /// </summary>
1888
        /// <param name="content">a document node representing the message content. Note the putput of <c>xsl:message</c>
1889
        /// is always an XML document node. It can be flattened to obtain the stringvalue if required by calling
1890
        /// <c>GetStringValue()</c></param>
1891
        /// <param name="errorCode">a QName containing the error supplied to the called on xsl:message, or its default of err:XTM9000.</param>
1892
        /// <param name="terminate">Set to true if <c>terminate ='yes'</c> was specified or to false otherwise</param>
1893
        /// <param name="location">an object that contains the location of the <c>xsl:message</c> This provides access to the URI of the stylesheet
1894
        /// module and the line number of the <c>xsl:message</c></param>
1895

    
1896
        /**public**/
1897
        void Message(XdmNode content, QName errorCode,  bool terminate, IXmlLocation location);
1898

    
1899
    }
1900

    
1901
    /// <summary>
1902
    /// An <c>IXmlLocation</c> represents the location of a node within an XML document.
1903
    /// It is in two parts: the base URI (or system ID) of the external entity (which will usually
1904
    /// be the XML document entity itself), and the line number of a node relative
1905
    /// to the base URI of the containing external entity.
1906
    /// </summary>
1907

    
1908
    public interface IXmlLocation
1909
    {
1910

    
1911
        /// <summary>
1912
        /// The base URI (system ID) of an external entity within an XML document.
1913
        /// Set to null if the base URI is not known (for example, for an XML document
1914
        /// created programmatically where no base URI has been set up).
1915
        /// </summary>
1916

    
1917
        /**public**/
1918
        Uri BaseUri { get; set; }
1919

    
1920
        /// <summary>
1921
        /// The line number of a node relative to the start of the external entity.
1922
        /// The value -1 indicates that the line number is not known or not applicable.
1923
        /// </summary>
1924

    
1925
        /**public**/
1926
        int LineNumber { get; set; }
1927
    }
1928

    
1929

    
1930
    /// <summary>
1931
	/// Xml location. An implementation of <c>IXmlLocation</c>.
1932
    /// </summary>
1933
    internal class XmlLocation : IXmlLocation
1934
    {
1935
        private Uri baseUri;
1936
        private int lineNumber;
1937
        public Uri BaseUri
1938
        {
1939
            get { return baseUri; }
1940
            set { baseUri = value; }
1941
        }
1942
        public int LineNumber
1943
        {
1944
            get { return lineNumber; }
1945
            set { lineNumber = value; }
1946
        }
1947
    }
1948

    
1949

    
1950
    /// <summary>
1951
    /// Message listener proxy. This class implements a <c>net.sf.saxon.s9api.MessageListener</c> that can receive 
1952
    /// <c>xsl:message</c> output and send it to a user-supplied <c>MessageListener</c>
1953
    /// </summary>
1954
    [Serializable]
1955
    internal class MessageListenerProxy : net.sf.saxon.s9api.MessageListener
1956
    {
1957

    
1958
        public IMessageListener listener;
1959

    
1960
        /// <summary>
1961
        /// Initializes a new instance of the <see cref="Saxon.Api.MessageListenerProxy"/> class.
1962
        /// </summary>
1963
        /// <param name="ml">ml.</param>
1964
        public MessageListenerProxy(IMessageListener ml)
1965
        {
1966
            listener = ml;
1967
        }
1968

    
1969

    
1970
        public void message(net.sf.saxon.s9api.XdmNode xn, bool b, SourceLocator sl)
1971
        {
1972
            IXmlLocation location = new XmlLocation();
1973
            location.BaseUri = new Uri(sl.getSystemId());
1974
            location.LineNumber = sl.getLineNumber();
1975
            listener.Message((XdmNode)XdmValue.Wrap(xn.getUnderlyingValue()), b, location);
1976
        }
1977
    }
1978

    
1979

    
1980

    
1981
    /// <summary>
1982
	/// Message listener proxy. This class implements a <c>net.sf.saxon.s9api.MessageListener2</c> that can receive 
1983
	/// <c>xsl:message</c> output and send it to a user-supplied <c>MessageListener</c>
1984
    /// </summary>
1985
    [Serializable]
1986
    internal class MessageListenerProxy2 : net.sf.saxon.s9api.MessageListener2
1987
    {
1988

    
1989
        public IMessageListener2 listener;
1990

    
1991
        /// <summary>
1992
        /// Initializes a new instance of the <see cref="Saxon.Api.MessageListenerProxy"/> class.
1993
        /// </summary>
1994
        /// <param name="ml">ml.</param>
1995
        public MessageListenerProxy2(IMessageListener2 ml)
1996
        {
1997
            listener = ml;
1998
        }
1999

    
2000

    
2001
        public void message(net.sf.saxon.s9api.XdmNode xn, net.sf.saxon.s9api.QName qn, bool b, SourceLocator sl)
2002
        {
2003
            IXmlLocation location = new XmlLocation();
2004
            location.BaseUri = new Uri(sl.getSystemId());
2005
            location.LineNumber = sl.getLineNumber();
2006
            listener.Message((XdmNode)XdmValue.Wrap(xn.getUnderlyingValue()), new QName(qn),b, location);
2007
        }
2008
    }
2009

    
2010

    
2011

    
2012
    /// <summary>An <code>Xslt30Transformer</code> represents a compiled and loaded stylesheet ready for execution.
2013
    /// The <code>Xslt30Transformer</code> holds details of the dynamic evaluation context for the stylesheet.</summary>
2014

    
2015
    /// <remarks><para>The <code>Xslt30Transformer</code> differs from <see cref="XsltTransformer"/> 
2016
    /// in supporting new options
2017
    /// for invoking a stylesheet, corresponding to facilities defined in the XSLT 3.0 specification. However,
2018
    /// it is not confined to use with XSLT 3.0, and most of the new invocation facilities (for example,
2019
    /// calling a stylesheet-defined function directly) work equally well with XSLT 2.0 and in some cases
2020
    /// XSLT 1.0 stylesheets.</para>
2021
    /// <para>An <code>Xslt30Transformer</code> must not be used concurrently in multiple threads.
2022
    /// It is safe, however, to reuse the object within a single thread to run the same
2023
    /// stylesheet several times. Running the stylesheet does not change the context
2024
    /// that has been established.</para>
2025

    
2026
    /// <para>An <code>Xslt30Transformer</code> is always constructed by running the <code>Load30</code>
2027
    /// method of an <see cref="XsltExecutable"/>.</para>
2028

    
2029
    /// <para>Unlike <code>XsltTransformer</code>, an <code>Xslt30Transformer</code> is not a <code>Destination</code>.
2030
    /// To pipe the results of one transformation into another, the target should be an <code>XsltTransfomer</code>
2031
    /// rather than an <code>Xslt30Transformer</code>.</para>
2032

    
2033
    /// <para>Evaluation of an Xslt30Transformer proceeds in a number of phases:</para>
2034
    /// <list type="number">
2035
    /// <item>First, values may be supplied for stylesheet parameters and for the global context item. The
2036
    /// global context item is used when initializing global variables. Unlike earlier transformation APIs,
2037
    /// the global context item is quite independent of the "principal source document".
2038
    /// </item>
2039
    /// <item>The stylesheet may now be repeatedly invoked. Each invocation takes
2040
    /// one of three forms:
2041
    /// <list type="number">
2042
    /// <item>Invocation by applying templates. In this case, the information required is (i) an initial
2043
    /// mode (which defaults to the unnamed mode), (ii) an initial match sequence, which is any
2044
    /// XDM value, which is used as the effective "select" expression of the implicit apply-templates
2045
    /// call, and (iii) optionally, values for the tunnel and non-tunnel parameters defined on the
2046
    /// templates that get invoked (equivalent to using <code>xsl:with-param</code> on the implicit
2047
    /// <code>apply-templates</code> call).</item>
2048
    /// <item>Invocation by calling a named template. In this case, the information required is
2049
    /// (i) the name of the initial template (which defaults to "xsl:initial-template"), and
2050
    /// (ii) optionally, values for the tunnel and non-tunnel parameters defined on the
2051
    /// templates that get invoked (equivalent to using <code>xsl:with-param</code> on the implicit
2052
    /// <code>call-template</code> instruction).</item>
2053
    /// <item>Invocation by calling a named function. In this case, the information required is
2054
    /// the sequence of arguments to the function call.</item>
2055
    /// </list>
2056
    /// </item>
2057
    /// <item>Whichever invocation method is chosen, the result may either be returned directly, as an arbitrary
2058
    /// XDM value, or it may effectively be wrapped in an XML document. If it is wrapped in an XML document,
2059
    /// that document can be processed in a number of ways, for example it can be materialized as a tree in
2060
    /// memory, it can be serialized as XML or HTML, or it can be subjected to further transformation.</item>
2061
    /// </list>
2062
    /// <para>Once the stylesheet has been invoked (using any of these methods), the values of the global context
2063
    /// item and stylesheet parameters cannot be changed. If it is necessary to run another transformation with
2064
    /// a different context item or different stylesheet parameters, a new <c>Xslt30Transformer</c>
2065
    /// should be created from the original <c>XsltExecutable</c>.</para>
2066
    /// <para> @since 9.6</para> 
2067
    /// </remarks>
2068

    
2069
    [Serializable]
2070
    public class Xslt30Transformer
2071
    {
2072

    
2073

    
2074
        private IResultDocumentHandler resultDocumentHandler;
2075
        private StandardLogger traceFunctionDestination;
2076
        private IMessageListener messageListener;
2077
        private IMessageListener2 messageListener2;
2078
        private JXslt30Transformer transformer;
2079

    
2080
		// internal constructor
2081

    
2082
        internal Xslt30Transformer(JXslt30Transformer transformer)
2083
        {
2084

    
2085
            this.transformer = transformer;
2086
            //this.globalParameterSet = new GlobalParameterSet(globalParameters);
2087
        }
2088

    
2089

    
2090
        /// <summary> Supply the context item to be used when evaluating global variables and parameters.
2091
        /// This argument can be null if no context item is to be supplied.</summary>
2092

    
2093
        public XdmItem GlobalContextItem
2094
        {
2095
            set
2096
            {
2097
               transformer.setGlobalContextItem(value == null ? null : XdmItem.FromXdmItemItemToJXdmItem(value));
2098
            }
2099
         
2100
            get { return (XdmItem)XdmItem.Wrap(transformer.getUnderlyingController().getGlobalContextItem()); }
2101

    
2102
        }
2103

    
2104

    
2105
		/// <summary> Get the underlying <c>Controller</c> used to implement this <c>XsltTransformer</c>. This provides access
2106
        /// to lower-level methods not otherwise available in the Saxon.Api interface. Note that classes
2107
        /// and methods obtained by this route cannot be guaranteed stable from release to release.</summary>
2108

    
2109
        public JXsltController GetUnderlyingController
2110
        {
2111
            get { return transformer.getUnderlyingController(); }
2112
        }
2113

    
2114
        internal JXslt30Transformer GetUnderlyingXslt30Transformer
2115
        {
2116
            get { return transformer; }
2117
        }
2118

    
2119

    
2120
        /// <summary>
2121
		/// Construct a <c>Destination</c> object whose effect is to perform this transformation
2122
		/// on any input that is sent to that <c>Destination</c>: for example, it allows this transformation
2123
		/// to post-process the results of another transformation.
2124
		/// </summary>
2125
		/// <remarks>
2126
        /// <para>This method allows a pipeline of transformations to be created in which
2127
        /// one transformation is used as the destination of another. The transformations
2128
        /// may use streaming, in which case intermediate results will not be materialized
2129
        /// in memory. If a transformation does not use streaming, then its input will
2130
        /// first be assembled in memory as a node tree.</para>
2131
		/// <para>The <c>Destination</c> returned by this method performs <em>sequence normalization</em>
2132
        /// as defined in the serialization specification: that is, the raw result of the transformation
2133
        /// sent to this destination is wrapped into a document node. Any item-separator present in
2134
        /// any serialization parameters is ignored (adjacent atomic values are separated by whitespace). 
2135
        /// This makes the method unsuitable for passing intermediate results other than XML document
2136
        /// nodes.</para>
2137
		/// </remarks>
2138
        /// <param name="finalDestination">supplied final destination</param>
2139
		/// <returns>a <c>Destination</c> which accepts an XML document (typically as a stream
2140
        /// of events) and which transforms this supplied XML document (possibly using streaming)
2141
		/// as defined by the stylesheet from which which this <c>Xslt30Transformer</c>
2142
        /// was generated,
2143
		/// sending the principal result of the transformation to the supplied <c>finalDestination</c>.
2144
		/// The transformation is performed as if by the <see cref="ApplyTemplates(Stream, XmlDestination)"/>
2145
        /// method: that is, by applying templates to the root node of the supplied XML document.
2146
		/// </returns>
2147
        public XmlDestination AsDocumentDestination(XmlDestination finalDestination) {
2148

    
2149
            AbstractDestination localDestination = new AbstractDestination(this, finalDestination);
2150
            return localDestination;
2151
        }
2152

    
2153
		// internal method
2154
        internal JReceiver GetDestinationReceiver(XmlDestination destination)
2155
        {
2156
            JReceiver r = transformer.getDestinationReceiver(transformer.getUnderlyingController(), destination.GetUnderlyingDestination()); 
2157
            return r;
2158
        }
2159

    
2160

    
2161

    
2162
        /// <summary>
2163
        /// The <c>IResultDocumentHandler</c> to be used at run-time to process the output
2164
        /// produced by any <c>xsl:result-document</c> instruction with an <c>href</c>
2165
        /// attribute.
2166
        /// </summary>
2167
        /// <remarks>
2168
        /// In the absence of a user-supplied result document handler, the <c>href</c>
2169
        /// attribute of the <c>xsl:result-document</c> instruction must be a valid relative
2170
        /// URI, which is resolved against the value of the <c>BaseOutputUri</c> property,
2171
        /// and the resulting absolute URI must identify a writable resource (typically
2172
        /// a file in filestore, using the <c>file:</c> URI scheme).
2173
        /// </remarks>
2174

    
2175
        public IResultDocumentHandler ResultDocumentHandler
2176
        {
2177
            get
2178
            {
2179
                return resultDocumentHandler;
2180
            }
2181
            set
2182
            {
2183
                resultDocumentHandler = value;
2184
                transformer.getUnderlyingController().setResultDocumentResolver(new ResultDocumentHandlerWrapper(value, transformer.getUnderlyingController().makePipelineConfiguration()));
2185
            }
2186
        }
2187

    
2188
        /// <summary>
2189
        /// The <c>SchemaValidationMode</c> to be used in this transformation, especially for documents
2190
        /// loaded using the <code>doc()</code>, <code>document()</code>, or <code>collection()</code> functions.
2191
        /// </summary>
2192

    
2193
        public SchemaValidationMode SchemaValidationMode
2194
        {
2195
            get
2196
            {
2197
                switch (transformer.getUnderlyingController().getSchemaValidationMode())
2198
                {
2199
                    case JValidation.STRICT:
2200
                        return SchemaValidationMode.Strict;
2201
                    case JValidation.LAX:
2202
                        return SchemaValidationMode.Lax;
2203
                    case JValidation.STRIP:
2204
                        return SchemaValidationMode.None;
2205
                    case JValidation.PRESERVE:
2206
                        return SchemaValidationMode.Preserve;
2207
                    case JValidation.DEFAULT:
2208
                    default:
2209
                        return SchemaValidationMode.Unspecified;
2210
                }
2211
            }
2212

    
2213

    
2214
            set
2215
            {
2216
                switch (value)
2217
                {
2218
                    case SchemaValidationMode.Strict:
2219
                        transformer.setSchemaValidationMode(JValidationMode.STRICT);
2220
                        break;
2221
                    case SchemaValidationMode.Lax:
2222
                        transformer.setSchemaValidationMode(JValidationMode.LAX);
2223
                        break;
2224
                    case SchemaValidationMode.None:
2225
                        transformer.setSchemaValidationMode(JValidationMode.STRIP);
2226
                        break;
2227
                    case SchemaValidationMode.Preserve:
2228
                        transformer.setSchemaValidationMode(JValidationMode.PRESERVE);
2229
                        break;
2230
                    case SchemaValidationMode.Unspecified:
2231
                    default:
2232
                        transformer.setSchemaValidationMode(JValidationMode.DEFAULT);
2233
                        break;
2234
                }
2235
            }
2236
        }
2237

    
2238

    
2239

    
2240
        /// <summary> Supply the values of global stylesheet variables and parameters.</summary>
2241
		/// <param name="parameters"> A <c>Dictionary</c> whose keys are QNames identifying global stylesheet parameters,
2242
        /// and whose corresponding values are the values to be assigned to those parameters. If necessary
2243
        /// the supplied values are converted to the declared type of the parameter.
2244
		/// The contents of the supplied <c>Dictionary</c> are copied by this method,
2245
		/// so subsequent changes to the <c>Dictionary</c> have no effect.</param>
2246
        
2247
        public void SetStylesheetParameters(Dictionary<QName, XdmValue> parameters)
2248
        {
2249
            try
2250
            {
2251
                JMap map = new java.util.HashMap();
2252
                foreach (KeyValuePair<QName, XdmValue> entry in parameters)
2253
                {
2254
                    QName qname = entry.Key;
2255
                    map.put(qname.UnderlyingQName(), XdmValue.FromGroundedValueToJXdmValue(entry.Value.value));
2256
                }
2257
                transformer.setStylesheetParameters(map);
2258

    
2259
            }
2260
            catch (net.sf.saxon.trans.XPathException e)
2261
            {
2262
                throw new StaticError(e);
2263
            }
2264

    
2265
        }
2266

    
2267

    
2268

    
2269
        /// <summary>Get the base output URI.</summary>
2270
        /// <remarks><para> This returns the value set using the setter method. If no value has been set
2271
        /// explicitly, then the method returns null if called before the transformation, or the computed
2272
        /// default base output URI if called after the transformation.
2273
        /// </para>
2274
        /// <para> The base output URI is used for resolving relative URIs in the <code>href</code> attribute
2275
        /// of the <code>xsl:result-document</code> instruction.</para></remarks>
2276
        /// <returns> The base output URI</returns>
2277

    
2278
        public String BaseOutputURI
2279
        {
2280
            set
2281
            {
2282
                transformer.setBaseOutputURI(value);
2283
            }
2284
            get { return transformer.getBaseOutputURI(); }
2285
        }
2286

    
2287
        /// <summary>
2288
        /// The <c>XmlResolver</c> to be used at run-time to resolve and dereference URIs
2289
        /// supplied to the <c>doc()</c> and <c>document()</c> functions.
2290
        /// </summary>
2291

    
2292
        public XmlResolver InputXmlResolver
2293
        {
2294
            get
2295
            {
2296
                return ((JDotNetURIResolver)transformer.getURIResolver()).getXmlResolver();
2297
            }
2298
            set
2299
            {
2300
                transformer.setURIResolver(new JDotNetURIResolver(value));
2301
            }
2302
        }
2303

    
2304
        /// <summary>
2305
        /// Ask whether assertions (<c>xsl:assert</c> instructions) have been enabled at run time. 
2306
        /// </summary>
2307
        /// <remarks>By default they are disabled at compile time. If assertions are enabled at compile time, then by
2308
        /// default they will also be enabled at run time; but they can be disabled at run time by
2309
        /// specific request. At compile time, assertions can be enabled for some packages and
2310
        /// disabled for others; at run time, they can only be enabled or disabled globally.</remarks>
2311
        /// <returns>true if assertions are enabled at run time</returns>
2312
        /// <remarks>Since 9.7</remarks>
2313
 
2314
        public bool AssertionsEnabled
2315
        {
2316
            get
2317
            {
2318
                return transformer.isAssertionsEnabled();
2319
            }
2320
        }
2321

    
2322

    
2323
        /// <summary>
2324
        /// Ask whether assertions (<c>xsl:assert</c> instructions) have been enabled at run time.
2325
        /// This property name has been misspelt, use <c>AssertionsEnabled</c> instead.
2326
        /// </summary>
2327
        [Obsolete("This property has been replaced by AssertionsEnabled.")]
2328
        public bool ssAssertionsEnabled
2329
        {
2330
            get
2331
            {
2332
                return transformer.isAssertionsEnabled();
2333
            }
2334
        }
2335

    
2336

    
2337
        /// <summary>
2338
		/// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
2339
		/// </summary>
2340
		/// <remarks> 
2341
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
2342
        /// the processor will then invoke the listener once for each message generated during
2343
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
2344
        /// representing a document node.</para>
2345
        /// <para>If no message listener is supplied by the caller, message information will be written to
2346
        /// the standard error stream.</para>
2347
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
2348
        /// on the message object will usually generate an acceptable representation of the
2349
        /// message.</para>
2350
		/// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
2351
        /// the message is first notified using this interface, and then an exception is thrown
2352
        /// which terminates the transformation.</para>
2353
        /// </remarks>
2354

    
2355
        public IMessageListener MessageListener
2356
        {
2357
            set
2358
            {
2359
                messageListener = value;
2360
                transformer.setMessageListener(new MessageListenerProxy(value));
2361
            }
2362
            get
2363
            {
2364
                return messageListener;
2365
            }
2366
        }
2367

    
2368

    
2369

    
2370
        /// <summary>
2371
        /// Listener for messages output using <c>&lt;xsl:message&gt;</c>.
2372
        /// </summary>
2373
        /// <remarks> 
2374
        /// <para>The caller may supply a message listener before calling <c>Run</c>;
2375
        /// the processor will then invoke the listener once for each message generated during
2376
        /// the transformation. Each message will be output as an object of type <c>XdmNode</c>
2377
        /// representing a document node.</para>
2378
        /// <para>If no message listener is supplied by the caller, message information will be written to
2379
        /// the standard error stream.</para>
2380
        /// <para>Each message is presented as an XML document node. Calling <c>ToString()</c>
2381
        /// on the message object will usually generate an acceptable representation of the
2382
        /// message.</para>
2383
        /// <para>When the <c>xsl:message</c> instruction specifies <c>terminate="yes"</c>,
2384
        /// the message is first notified using this interface, and then an exception is thrown
2385
        /// which terminates the transformation.</para>
2386
        /// <para>The <c>MessageListener2</c> property interface differs from the <c>MessageListener</c>
2387
        /// in allowing the error code supplied to xsl:message to be notified</para>
2388
        /// </remarks>
2389

    
2390
        public IMessageListener2 MessageListener2
2391
        {
2392
            set
2393
            {
2394
                messageListener2 = value;
2395
                transformer.setMessageListener(new MessageListenerProxy2(value));
2396
            }
2397
            get
2398
            {
2399
                return messageListener2;
2400
            }
2401
        }
2402

    
2403
        /// <summary>
2404
        /// Destination for output of messages using the <c>trace()</c> function. 
2405
        /// </summary>
2406
		/// <remarks>
2407
		/// <para>If no message listener is supplied by the caller, message information will be written to
2408
		/// the standard error stream.</para>
2409
        /// <para>The supplied destination is ignored if a <code>TraceListener</code> is in use.</para>
2410
        /// </remarks>
2411

    
2412
        public StandardLogger TraceFunctionDestination
2413
        {
2414
            set
2415
            {
2416
                traceFunctionDestination = value;
2417
                transformer.setTraceFunctionDestination(value);
2418
            }
2419
            get
2420
            {
2421
                return traceFunctionDestination;
2422
            }
2423
        }
2424

    
2425

    
2426
        /// <summary>Set parameters to be passed to the initial template. These are used
2427
        /// whether the transformation is invoked by applying templates to an initial source item,
2428
        /// or by invoking a named template. The parameters in question are the <c>xsl:param</c> elements
2429
        /// appearing as children of the <c>xsl:template</c> element.
2430
		/// </summary>
2431
        /// <remarks>
2432
        /// <para>The parameters are supplied in the form of a map; the key is a <c>QName</c> which must
2433
        /// match the name of the parameter; the associated value is an <c>XdmValue</c> containing the
2434
        /// value to be used for the parameter. If the initial template defines any required
2435
        /// parameters, the map must include a corresponding value. If the initial template defines
2436
        /// any parameters that are not present in the map, the default value is used. If the map
2437
        /// contains any parameters that are not defined in the initial template, these values
2438
        /// are silently ignored.</para>
2439
        /// <para>The supplied values are converted to the required type using the function conversion
2440
        /// rules. If conversion is not possible, a run-time error occurs (not now, but later, when
2441
        /// the transformation is actually run).</para>
2442
        /// <para>The <code>Xslt30Transformer</code> retains a reference to the supplied map, so parameters can be added or
2443
        /// changed until the point where the transformation is run.</para>
2444
        /// <para>The XSLT 3.0 specification makes provision for supplying parameters to the initial
2445
        /// template, as well as global stylesheet parameters. Although there is no similar provision
2446
        /// in the XSLT 1.0 or 2.0 specifications, this method works for all stylesheets, regardless whether
2447
        /// XSLT 3.0 is enabled or not.</para></remarks>
2448

    
2449
        /// <param name="parameters"> The parameters to be used for the initial template</param>
2450
        /// <param name="tunnel"> true if these values are to be used for setting tunnel parameters;
2451
        /// false if they are to be used for non-tunnel parameters</param>
2452
        
2453
        public void SetInitialTemplateParameters(Dictionary<QName, XdmValue> parameters, bool tunnel)
2454
        {
2455

    
2456
            JMap templateParameters = new java.util.HashMap();
2457
            foreach (KeyValuePair<QName, XdmValue> entry in parameters)
2458
            {
2459
                QName qname = entry.Key;
2460
                templateParameters.put(qname.UnderlyingQName(), XdmValue.FromGroundedValueToJXdmValue(entry.Value.value));
2461
            }
2462

    
2463
            transformer.setInitialTemplateParameters(templateParameters, tunnel);
2464

    
2465

    
2466
        }
2467

    
2468

    
2469
        /// <summary>Initial mode for the transformation. This is used if the stylesheet is
2470
        /// subsequently invoked by any of the <code>applyTemplates</code> methods.</summary>
2471
        /// <remarks><para>The value may be the name of the initial mode, or null to indicate the default
2472
        /// (unnamed) mode</para></remarks>
2473

    
2474
        public QName InitialMode
2475
        {
2476

    
2477
            set
2478
            {
2479
                try
2480
                {
2481
                    transformer.setInitialMode(value == null ? null : value.UnderlyingQName());
2482
                }
2483
                catch (net.sf.saxon.trans.XPathException e)
2484
                {
2485
                    throw new DynamicError(e);
2486
                }
2487
            }
2488
            get
2489
            {
2490
                net.sf.saxon.s9api.QName mode = transformer.getInitialMode();
2491
                if (mode == null)
2492
                    return null;
2493
                else
2494
                {
2495
                    return new QName(mode);
2496
                }
2497
            }
2498

    
2499

    
2500
        }
2501

    
2502

    
2503
        /// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2504
		/// sending the results (wrapped in a document node) to a given <c>Destination</c>. The 
2505
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2506
        /// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2507
        /// </summary>
2508
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2509
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2510
        /// <param name="destination">The destination of the result document produced by wrapping the result 
2511
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2512
		/// then the serialization parameters set in the serializer are combined with those defined in the 
2513
		/// stylesheet (the parameters set in the serializer take precedence).</param>
2514

    
2515
        public void ApplyTemplates(Stream input, XmlDestination destination)
2516
        {
2517
            try
2518
            {
2519
                JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input));
2520
                transformer.applyTemplates(streamSource, destination.GetUnderlyingDestination());
2521
            
2522
            }
2523
            catch (JSaxonApiException exp)
2524
            {
2525
                throw new DynamicError(exp);
2526
            }
2527

    
2528
        }
2529

    
2530

    
2531
		/// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2532
		/// using the supplied base URI,
2533
		/// sending the results (wrapped in a document node) to a given <c>Destination</c>. The 
2534
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2535
		/// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2536
		/// </summary>
2537
		/// <param name="input">The source document. To apply more than one transformation to the same source 
2538
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2539
		/// <param name="baseUri">Base URI used for the input document</param>
2540
		/// <param name="destination">The destination of the result document produced by wrapping the result 
2541
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2542
		/// then the serialization parameters set in the serializer are combined with those defined in the 
2543
		/// stylesheet (the parameters set in the serializer take precedence).</param>
2544

    
2545
        public void ApplyTemplates(Stream input, Uri baseUri, XmlDestination destination)
2546
        {
2547
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2548
            try
2549
            {
2550
                transformer.applyTemplates(streamSource, destination.GetUnderlyingDestination());
2551
            }
2552
            catch (JSaxonApiException exp)
2553
            {
2554
                throw new DynamicError(exp.getMessage());
2555
            }
2556

    
2557
        }
2558

    
2559

    
2560
        /// <summary>
2561
        /// Invoke the stylesheet by applying templates to a supplied source document, sending the results
2562
        /// to a given <c>Destination</c>. The invocation uses the initial mode set using <see cref="InitialMode"/>
2563
        /// (defaulting to the default mode defined in the stylesheet itself, which by default is the unnamed mode).
2564
        /// It also uses any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2565
        /// </summary>
2566
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2567
        /// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2568
        /// <param name="destination">The destination of the principal result of the transformation.
2569
        /// If the destination is a <see cref="Serializer"/>, then the serialization
2570
        /// parameters set in the serializer are combined with those defined in the stylesheet
2571
        /// (the parameters set in the serializer take precedence).</param>
2572
        /// <remarks>since 9.9.1.5</remarks>
2573
        public void Transform(Stream input, XmlDestination destination) {
2574
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input));
2575

    
2576
            try
2577
            {
2578
                transformer.transform(streamSource, destination.GetUnderlyingDestination());
2579
            }
2580
            catch (JSaxonApiException exp)
2581
            {
2582
                throw new DynamicError(exp.getMessage());
2583
            }
2584

    
2585
        }
2586

    
2587
        /// <summary>
2588
        /// Invoke the stylesheet by applying templates to a supplied Source document,  
2589
        /// using the supplied base URI, sending the results
2590
        /// to a given <c>Destination</c>. The invocation uses the initial mode set using <see cref="InitialMode"/>
2591
        /// (defaulting to the default mode defined in the stylesheet itself, which by default is the unnamed mode).
2592
        /// It also uses any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2593
        /// </summary>
2594
        /// <param name="input">The source document. To apply more than one transformation to the same source 
2595
        /// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2596
        /// <param name="baseUri">Base URI used for the input document</param>
2597
        /// <param name="destination">The destination of the principal result of the transformation.
2598
        /// If the destination is a <see cref="Serializer"/>, then the serialization
2599
        /// parameters set in the serializer are combined with those defined in the stylesheet
2600
        /// (the parameters set in the serializer take precedence).</param>
2601
        /// <remarks>since 9.9.1.5</remarks>
2602
        public void Transform(Stream input, Uri baseUri, XmlDestination destination)
2603
        {
2604
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2605
            try
2606
            {
2607
                transformer.transform(streamSource, destination.GetUnderlyingDestination());
2608
            }
2609
            catch (JSaxonApiException exp)
2610
            {
2611
                throw new DynamicError(exp.getMessage());
2612
            }
2613

    
2614
        }
2615

    
2616

    
2617

    
2618

    
2619
        /// <summary>Invoke the stylesheet by applying templates to a supplied source document, 
2620
		/// using the supplied base URI,
2621
		/// returning the raw results as an <c>XdmValue</c>. The 
2622
		/// invocation uses any initial mode set using <see cref="InitialMode"/>,
2623
		/// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2624
		/// </summary>
2625
		/// <param name="input">The source document. To apply more than one transformation to the same source 
2626
		/// document, the source document tree can be pre-built using a <see cref="DocumentBuilder"/>.</param>
2627
		/// <param name="baseUri">Base URI</param>
2628
		/// <returns>the raw result of applying templates to the supplied selection value, without wrapping in
2629
        /// a document node or serializing the result. If there is more than one item in the selection, the result
2630
        /// is the concatenation of the results of applying templates to each item in turn.</returns>
2631

    
2632
        public XdmValue ApplyTemplates(Stream input, Uri baseUri)
2633
        {
2634
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2635

    
2636
            try
2637
            {
2638
                net.sf.saxon.s9api.XdmValue value = transformer.applyTemplates(streamSource);
2639
                return XdmValue.Wrap(value.getUnderlyingValue());
2640

    
2641
            }
2642
            catch (JSaxonApiException exp)
2643
            {
2644
                throw new DynamicError(exp);
2645
            }
2646

    
2647
        }
2648

    
2649

    
2650
        /// <summary>
2651
        /// Invoke the stylesheet by applying templates to a supplied input sequence, sending the results (wrapped
2652
		/// in a document node) to a given <c>Destination</c>. The invocation uses any initial mode set using 
2653
		/// <see cref="InitialMode"/>, and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2654
        /// </summary>
2655
        /// <param name="selection">The initial value to which templates are to be applied (equivalent to the <code>select</code>
2656
        /// attribute of <code>xsl:apply-templates</code>)</param>
2657
        /// <param name="destination">The destination of the result document produced by wrapping the result of the apply-templates
2658
        /// call in a document node.  If the destination is a <see cref="Serializer"/>, then the serialization
2659
        /// parameters set in the serializer are combined with those defined in the stylesheet
2660
        /// (the parameters set in the serializer take precedence).</param>
2661

    
2662
        public void ApplyTemplates(XdmValue selection, XmlDestination destination)
2663
        {
2664
            
2665
            try
2666
            {
2667
                transformer.applyTemplates(selection == null ? null : XdmValue.FromGroundedValueToJXdmValue(selection.value), destination.GetUnderlyingDestination());
2668
            }
2669
            catch (JSaxonApiException ex)
2670
            {
2671

    
2672
                throw new DynamicError(ex);
2673
            }
2674

    
2675
        }
2676

    
2677

    
2678

    
2679
        /// <summary>
2680
        /// Invoke the stylesheet by applying templates to a supplied input sequence, returning the raw results
2681
        /// as an <see cref="XdmValue"/>. The invocation uses any initial mode set using <see cref="InitialMode"/>,
2682
        /// and any template parameters set using <see cref="SetInitialTemplateParameters"/>.
2683
        /// </summary>
2684
        /// <param name="selection">The initial value to which templates are to be applied (equivalent to the <code>select</code>
2685
        /// attribute of <code>xsl:apply-templates</code>)</param>
2686
        /// <returns>the raw result of applying templates to the supplied selection value, without wrapping in
2687
        /// a document node or serializing the result. If there is more than one item in the selection, the result
2688
        /// is the concatenation of the results of applying templates to each item in turn.</returns>
2689

    
2690
        public XdmValue ApplyTemplates(XdmValue selection)
2691
        {
2692
           
2693
            try
2694
            {
2695
                return XdmValue.Wrap(transformer.applyTemplates(selection == null ? null : XdmValue.FromGroundedValueToJXdmValue(selection.value)).getUnderlyingValue());
2696
               
2697
            }
2698
            catch (JSaxonApiException ex)
2699
            {
2700

    
2701
                throw new DynamicError(ex);
2702
            }
2703

    
2704
        }
2705

    
2706

    
2707
        /// <summary> Invoke a transformation by calling a named template. The results of calling
2708
        /// the template are wrapped in a document node, which is then sent to the specified
2709
        /// destination. If <see cref="SetInitialTemplateParameters"/> has been
2710
        /// called, then the parameters supplied are made available to the called template (no error
2711
        /// occurs if parameters are supplied that are not used).</summary> 
2712
        /// <param name="templateName"> The name of the initial template. This must match the name of a
2713
        /// public named template in the stylesheet. If the value is null,
2714
        /// the QName <code>xsl:initial-template</code> is used.</param>
2715
        /// <param name="destination"> The destination of the result document produced by wrapping the result 
2716
		/// of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2717
		/// then the serialization parameters set in the serializer are combined with those defined in the stylesheet
2718
        /// (the parameters set in the serializer take precedence).</param> 
2719

    
2720
        public void CallTemplate(QName templateName, XmlDestination destination)
2721
        {
2722
           
2723
            if (templateName == null)
2724
            {
2725
                templateName = new QName("xsl", NamespaceConstant.XSLT, "initial-template");
2726
            }
2727

    
2728
            try
2729
            {
2730
                transformer.callTemplate(templateName.UnderlyingQName(), destination.GetUnderlyingDestination());
2731
               
2732
            }
2733
            catch (JSaxonApiException exp)
2734
            {
2735
                throw new DynamicError(exp);
2736
            }
2737
        }
2738

    
2739

    
2740

    
2741
        /// <summary>
2742
        /// Invoke a transformation by calling a named template. The results of calling
2743
        /// the template are returned as a raw value, without wrapping in a document nnode
2744
        /// or serializing.
2745
        /// </summary>
2746
        /// <param name="templateName">The name of the initial template. This must match the name of a
2747
        /// public named template in the stylesheet. If the value is null, the QName <c>xsl:initial-template</c> is used.</param>
2748
        /// <returns>the raw results of the called template, without wrapping in a document node or serialization.</returns>
2749

    
2750
        public XdmValue CallTemplate(QName templateName)
2751
        {
2752
            if (templateName == null)
2753
            {
2754
                templateName = new QName("xsl", NamespaceConstant.XSLT, "initial-template");
2755
            }
2756

    
2757
            try
2758
            {
2759
                return XdmValue.Wrap(transformer.callTemplate(templateName.UnderlyingQName()).getUnderlyingValue());
2760
            }
2761
            catch (JSaxonApiException exp)
2762
            {
2763
                throw new DynamicError(exp);
2764
            }
2765
        }
2766

    
2767

    
2768
        /// <summary> Call a public user-defined function in the stylesheet. </summary>
2769
        /// <param name="function"> The name of the function to be called</param>
2770
        /// <param name="arguments">  The values of the arguments to be supplied to the function. These
2771
        /// will be converted if necessary to the type as defined in the function signature, using
2772
        /// the function conversion rules.</param>
2773
        /// <returns> the result of calling the function. This is the raw result, without wrapping in a document
2774
        /// node and without serialization.</returns>
2775

    
2776
        public XdmValue CallFunction(QName function, XdmValue[] arguments)
2777
        {
2778
            try
2779
            {
2780
                int len = arguments.Length;
2781
                net.sf.saxon.s9api.XdmValue[] values = new net.sf.saxon.s9api.XdmValue[len];
2782

    
2783
                for (int i=0; i<len; i++) {
2784
                    values[i] = XdmValue.FromGroundedValueToJXdmValue(arguments[i].value);
2785

    
2786
                }
2787

    
2788
                return XdmValue.Wrap(transformer.callFunction(function.UnderlyingQName(), values).getUnderlyingValue());
2789

    
2790
            }
2791
            catch (JSaxonApiException ex)
2792
            {
2793
                throw new DynamicError(ex);
2794

    
2795
            }
2796

    
2797
        }
2798

    
2799

    
2800

    
2801
        /// <summary>Call a public user-defined function in the stylesheet, wrapping the result in an XML document, 
2802
		/// and sending this document to a specified destination</summary>    
2803
        /// <param name="function"> The name of the function to be called</param>
2804
        /// <param name="arguments"> The values of the arguments to be supplied to the function. These
2805
        /// will be converted if necessary to the type as defined in the function signature, using
2806
        /// the function conversion rules.</param>
2807
        /// <param name="destination"> The destination of the result document produced by wrapping the 
2808
		/// result of the apply-templates call in a document node.  If the destination is a <see cref="Serializer"/>, 
2809
		/// then the serialization parameters set in the serializer are combined with those defined in the stylesheet
2810
        /// (the parameters set in the serializer take precedence).</param>
2811

    
2812
        public void CallFunction(QName function, XdmValue[] arguments, XmlDestination destination)
2813
        {
2814

    
2815
            int len = arguments.Length;
2816
            net.sf.saxon.s9api.XdmValue[] values = new net.sf.saxon.s9api.XdmValue[len];
2817

    
2818
            for (int i = 0; i < len; i++)
2819
            {
2820
                values[i] = XdmValue.FromGroundedValueToJXdmValue(arguments[i].value);
2821

    
2822
            }
2823
            try
2824
            {
2825
                transformer.callFunction(function.UnderlyingQName(), values, destination.GetUnderlyingDestination());
2826

    
2827
            }
2828
            catch (JSaxonApiException ex) {
2829
                throw new DynamicError(ex);
2830
            }
2831
        }
2832

    
2833

    
2834
    }
2835

    
2836
    /// <summary> An <c>XsltPackage</c> object represents the result of compiling an XSLT 3.0 package, as
2837
    /// represented by an XML document containing an <c>xsl:package</c> element.</summary>
2838

    
2839
    [Serializable]
2840
    public class XsltPackage
2841
    {
2842
        private JXsltPackage package;
2843
        private Processor processor;
2844
		// internal constructor: Initializes a new instance of the <see cref="Saxon.Api.XsltPackage"/> class.
2845
        internal XsltPackage(Processor p, JXsltPackage pp)
2846
        {
2847
            this.package = pp;
2848
            this.processor = p;
2849

    
2850
        }
2851

    
2852
        /// <summary>
2853
        /// Get the Processor from which this <c>XsltPackage</c> was constructed
2854
        /// </summary>
2855

    
2856
        public Processor Processor
2857
        {
2858
            get { return processor; }
2859
        }
2860

    
2861

    
2862
        /// <summary>
2863
        /// Get the name of the package (the URI appearing as the value of <code>xsl:package/@name</code>)
2864
        /// </summary>
2865
        /// <returns>The package name</returns>
2866

    
2867
        public String PackageName
2868
        {
2869
            get { return package.getName(); }
2870
        }
2871

    
2872

    
2873
        /// <summary>Get the version number of the package (the value of the attribute 
2874
		/// <code>xsl:package/@package-version</code></summary>
2875
        /// <returns>The package version number</returns>
2876

    
2877
        public String Version
2878
        {
2879
            get { return package.getVersion(); }
2880
        }
2881

    
2882

    
2883
        /// <summary>Link this package with the packages it uses to form an executable stylesheet. This process fixes
2884
        /// up any cross-package references to files, templates, and other components, and checks to ensure
2885
        /// that all such references are consistent.</summary>
2886
		/// <returns> the resulting <c>XsltExecutable</c></returns>
2887

    
2888
        public XsltExecutable Link()
2889
        {
2890
            try
2891
            {
2892
                JXsltExecutable jexecutable = package.link();
2893
                XsltExecutable executable = new XsltExecutable(jexecutable);
2894
                executable.InternalProcessor = processor;
2895
                return executable;
2896
            }
2897
            catch (net.sf.saxon.trans.XPathException e)
2898
            {
2899
                throw new StaticError(e);
2900
            }
2901
        }
2902

    
2903
        /// <summary>Save this compiled package to filestore.</summary>
2904
        /// <param name="stream"> the stream to which the compiled package should be saved</param>
2905

    
2906
        public void Save(Stream stream)
2907
        {
2908
            JDotNetOutputStream outputStream = new JDotNetOutputStream(stream);
2909
            JExpressionPresenter outp = new JExpressionPresenter(package.getProcessor().getUnderlyingConfiguration(), new javax.xml.transform.stream.StreamResult(outputStream), true);
2910
            try
2911
            {
2912
                package.getUnderlyingPreparedPackage().export(outp);
2913
            }
2914
            catch (net.sf.saxon.trans.XPathException e)
2915
            {
2916
                throw new StaticError(e);
2917
            }
2918
        }
2919

    
2920

    
2921
        /// <summary>Escape-hatch interface to the underlying implementation class.</summary>
2922
		/// <returns>the underlying <c>StylesheetPackage</c>. The interface to <c>StylesheetPackage</c>
2923
        /// is not a stable part of the s9api API definition.</returns>
2924

    
2925
        public JStylesheetPackage getUnderlyingPreparedPackage()
2926
        {
2927
            return package.getUnderlyingPreparedPackage();
2928
        }
2929

    
2930
        internal JXsltPackage GetUnderlyingXsltPackage() {
2931
            return package;
2932
        }
2933
        
2934
    }
2935

    
2936

    
2937
}
2938

    
2939
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2940
// Copyright (c) 2020 Saxonica Limited.
2941
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
2942
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
2943
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
2944
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(11-11/11)