Project

Profile

Help

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

he / latest10 / hen / csource / api / Saxon.Api / Xslt.cs @ 8e927388

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

    
737
        public XsltExecutable Compile(TextReader input)
738
        {
739
            try {
740
                JStreamSource ss = new JStreamSource(new JDotNetReader(input));
741
                if (baseUri != null)
742
                {
743
                    ss.setSystemId(Uri.EscapeUriString(baseUri.ToString()));
744
                }
745

    
746
                XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(ss));
747
                executable.InternalProcessor = processor;
748
                return executable;
749
            }
750
            catch (JSaxonApiException ex) {
751
                throw new StaticError(ex);
752
            }
753
        }
754

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

    
770
        public XsltExecutable Compile(Uri uri)
771
        {
772
            Object obj = XmlResolver.GetEntity(uri, "application/xml", Type.GetType("System.IO.Stream"));
773
            if (obj is Stream)
774
            {
775

    
776
                // See bug issue #2306
777
                XsltExecutable executable = Compile((Stream)obj, uri.ToString(), true);
778
                executable.InternalProcessor = processor;
779
                return executable;
780

    
781
            }
782
            else
783
            {
784
                throw new ArgumentException("Invalid type of result from XmlResolver.GetEntity: " + obj);
785
            }
786
        }
787

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

    
815

    
816
        public XsltExecutable Compile(XmlReader reader)
817
        {
818
            JDotNetPullProvider pp = new JDotNetPullProvider(reader);
819
            JPipelineConfiguration pipe = processor.Implementation.makePipelineConfiguration();
820
            pp.setPipelineConfiguration(pipe);
821
            // pp = new PullTracer(pp);  /* diagnostics */
822
            JPullSource source = new JPullSource(pp);
823
            String baseu = reader.BaseURI;
824
            if (baseu == null || baseu == String.Empty)
825
            {
826
                // if no baseURI is supplied by the XmlReader, use the one supplied to this Compiler
827
                if (baseUri == null)
828
                {
829
                    throw new ArgumentNullException("BaseUri");
830
                }
831
                baseu = Uri.EscapeUriString(baseUri.ToString());
832
                pp.setBaseURI(baseu);
833
            }
834
            source.setSystemId(baseu);
835
            try {
836

    
837
                XsltExecutable executable =  new XsltExecutable(xsltCompiler.compile(source));
838
                executable.InternalProcessor = processor;
839
                return executable;
840
            }
841
            catch (JSaxonApiException e) {
842
                throw new StaticError(e);
843
            }
844

    
845
            }
846

    
847
        /// <summary>
848
		/// Compile a stylesheet, located at an <c>XdmNode</c>. This may be a document node whose
849
        /// child is an <c>xsl:stylesheet</c> or <c>xsl:transform</c> element, or it may be
850
        /// the <c>xsl:stylesheet</c> or <c>xsl:transform</c> element itself.
851
        /// </summary>
852
        /// <param name="node">The document node or the outermost element node of the document
853
        /// containing the principal stylesheet module.</param>
854
        /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.
855
		/// The <c>XsltExecutable</c> may be run as many times as required, in the same or a different
856
        /// thread. The <c>XsltExecutable</c> is not affected by any changes made to the <c>XsltCompiler</c>
857
        /// once it has been compiled.</returns>
858

    
859
        public XsltExecutable Compile(XdmNode node)
860
        {
861
            XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(node.Implementation));
862
            executable.InternalProcessor = processor;
863
            return executable;
864
        }
865

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

    
878
        public XsltExecutable CompileAssociatedStylesheet(Uri uri, String media)
879
        {
880

    
881
            Object obj = XmlResolver.GetEntity(uri, media == null ? "application/xml" : media, Type.GetType("System.IO.Stream"));
882
            if (obj is Stream)
883
            {
884
                JStreamSource ss = new JStreamSource(new JDotNetInputStream((Stream)obj));
885

    
886
                ss.setSystemId(Uri.EscapeUriString(uri.ToString()));
887
                try
888
                {
889

    
890
                    // See bug issue #2306
891
                    XsltExecutable executable = new XsltExecutable(xsltCompiler.compile(xsltCompiler.getAssociatedStylesheet(ss, media, null, null)));
892
                    executable.InternalProcessor = processor;
893
                    return executable;
894

    
895
                }
896
                catch (JSaxonApiException e)
897
                {
898
                    throw new StaticError(e);
899
                }
900

    
901
            }
902
            else
903
            {
904
                throw new ArgumentException("Invalid type of result from XmlResolver.GetEntity: " + obj);
905

    
906
            }
907
         
908
        }
909

    
910
            /// <summary>Locate and compile a stylesheet identified by an <c>&lt;?xml-stylesheet?&gt;</c>
911
            /// processing instruction within a source document.
912
            /// </summary>
913
            /// <param name="source">The document node of the source document containing the
914
            /// xml-stylesheet processing instruction.</param>
915
            /// <returns>An <c>XsltExecutable</c> which represents the compiled stylesheet object.</returns>
916
            /// <remarks>There are some limitations in the current implementation. The media type
917
            /// is ignored, as are the other parameters of the xml-stylesheet instruction. The
918
            /// <c>href</c> attribute must either reference an embedded stylesheet within the same
919
            /// document or a non-embedded external stylesheet.</remarks>
920

    
921
            public XsltExecutable CompileAssociatedStylesheet(XdmNode source)
922
        {
923

    
924

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

    
997
    /// <summary>
998
    /// An <c>XsltExecutable</c> represents the compiled form of a stylesheet. To execute the stylesheet,
999
	/// it must first be loaded to form an <see cref="XsltTransformer"/> or <see cref="Xslt30Transformer"/>.
1000
    /// </summary>
1001
    /// <remarks>
1002
    /// <para>An <c>XsltExecutable</c> is immutable, and therefore thread-safe. It is simplest to
1003
    /// load a new <c>XsltEvaluator</c> each time the stylesheet is to be run. However, the 
1004
    /// <c>XsltEvaluator</c> is serially reusable within a single thread.</para>
1005
    /// <para>An <c>XsltExecutable</c> is created by using one of the <c>Compile</c>
1006
	/// methods on the <see cref="XsltCompiler"/> class.</para>
1007
    /// </remarks>    
1008

    
1009
    [Serializable]
1010
    public class XsltExecutable
1011
    {
1012

    
1013
        // private JPreparedStylesheet pss;
1014
        private Processor processor;
1015
        private JXsltExecutable executable;
1016

    
1017
        // internal constructor
1018

    
1019
        internal XsltExecutable(JXsltExecutable executable)
1020
        {
1021
            //this.processor = proc;
1022
            this.executable = executable;
1023
        }
1024

    
1025
        internal Processor InternalProcessor
1026
        { 
1027
            set { processor = value;}
1028

    
1029
        }
1030

    
1031
        /// <summary>
1032
        /// Get the Processor that was used to create this XsltExecutable
1033
        /// </summary>
1034
        public Processor Processor
1035
        {
1036
            get { return processor; }
1037

    
1038
        }
1039

    
1040
        /// <summary>
1041
        /// Load the stylesheet to prepare it for execution.
1042
        /// </summary>
1043
        /// <returns>
1044
        /// An <c>XsltTransformer</c>. The returned <c>XsltTransformer</c> can be used to
1045
        /// set up the dynamic context for stylesheet evaluation, and to run the stylesheet.
1046
        /// </returns>
1047

    
1048
        public XsltTransformer Load()
1049
        {
1050
           // JXsltController c = pss.newController();
1051
            return new XsltTransformer(executable.load());
1052
        }
1053

    
1054

    
1055

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

    
1070
        public Xslt30Transformer Load30()
1071
        {
1072
            return new Xslt30Transformer(executable.load30());
1073
        }
1074

    
1075
        /// <summary>
1076
        /// Output an XML representation of the compiled code of the stylesheet, for purposes of 
1077
        /// diagnostics and instrumentation.
1078
        /// </summary>
1079
        /// <param name="destination">The destination for the diagnostic output</param>
1080

    
1081
        public void Explain(XmlDestination destination)
1082
        {
1083
            executable.explain(destination.GetUnderlyingDestination());
1084
        }
1085

    
1086
        /// <summary>
1087
        /// Escape hatch to the underlying Java implementation object.
1088
        /// </summary>
1089

    
1090
        public JXsltExecutable Implementation
1091
        {
1092
            get
1093
            {
1094
                return executable;
1095
            }
1096
        }
1097

    
1098
        /// <summary>
1099
        /// Get the whitespace stripping policy defined by this stylesheet, that is, the policy
1100
        /// defined by the <c>xsl:strip-space</c> and <c>xsl:preserve-space</c> elements in the stylesheet.
1101
        /// </summary>
1102
        /// <returns> a newly constructed <c>WhitespacePolicy</c> based on the declarations in this
1103
        /// stylesheet. This policy can be used as input to a <see cref="DocumentBuilder"/>.</returns>
1104
        
1105
        public WhitespacePolicy getWhitespaceStrippingPolicy() {
1106
            return new WhitespacePolicy(executable);
1107
        }
1108

    
1109

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

    
1131
            }
1132
            return params1;
1133
        }
1134

    
1135
        /// <summary>
1136
        /// Information about a global parameter to a stylesheet.
1137
        /// </summary>
1138

    
1139
        public class ParameterDetails
1140
        {
1141
            private XdmSequenceType type;
1142
            private bool isRequired;
1143

    
1144
            /// <summary>
1145
            /// Create parameter details.
1146
            /// </summary>
1147
            /// <param name="type">The declared type of the parameter.</param>
1148
            /// <param name="isRequired">Indicates whether the parameter is required or optional.</param>
1149
            
1150
            public ParameterDetails(XdmSequenceType type, bool isRequired)
1151
            {
1152
                this.type = type;
1153
                this.isRequired = isRequired;
1154
            }
1155

    
1156
            /// <summary>
1157
            /// Gets the declared item type of the parameter.
1158
            /// </summary>
1159
            /// <returns>The type defined in the <code>as</code> attribute of the <code>xsl:param</code> element,
1160
            /// without its occurrence indicator</returns>
1161
            public XdmItemType GetDeclaredItemType()
1162
            {
1163
                return type.itemType;
1164
            }
1165

    
1166

    
1167
            /// <summary>
1168
            /// Gets the declared cardinality of the parameter.
1169
            /// </summary>
1170
            /// <returns>The occurrence indicator from the type appearing in the <code>as</code> attribute
1171
            /// of the <code>xsl:param</code> element</returns>
1172

    
1173
            public char GetDeclaredCardinality()
1174
            {
1175
                return type.occurrenceIn;
1176
            }
1177

    
1178
            /// <summary>
1179
            /// Gets the underlying declared type of the parameter.
1180
            /// </summary>
1181
            /// <returns>The underlying declared type.</returns>
1182

    
1183
            public XdmSequenceType GetUnderlyingDeclaredType()
1184
            {
1185
                return type;
1186
            }
1187

    
1188

    
1189
            /// <summary>
1190
            /// Ask whether the parameter is required (mandatory) or optional
1191
            /// </summary>
1192
            /// <returns><c>true</c> if the parameter is mandatory (<code>required="yes"</code>), false
1193
            /// if it is optional.</returns>
1194

    
1195
            public bool IsRequired
1196
            {
1197
                set { this.isRequired = value; }
1198
                get { return this.isRequired; }
1199

    
1200
            }
1201
        }
1202

    
1203

    
1204

    
1205

    
1206
    }
1207

    
1208

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

    
1224
    [Serializable]
1225
    public class XsltTransformer : XmlDestination
1226
    {
1227

    
1228
        /* private JXsltController controller;
1229
      
1230
         private JStreamSource streamSource;
1231
         private GlobalParameterSet globalParameters;
1232
         private bool baseOutputUriWasSet = false;*/
1233
        private XmlDestination xmlDestination;
1234
        private StandardLogger traceFunctionDestination;
1235
        private IMessageListener messageListener;
1236
        private IMessageListener2 messageListener2;
1237
        private IResultDocumentHandler resultDocumentHandler;
1238
        private QName initialTemplateName;
1239
        private XdmNode initialContextNode;
1240
        private JXsltTransformer transformer;
1241

    
1242
        // internal constructor
1243

    
1244
        internal XsltTransformer(JXsltTransformer transformer)
1245
        {
1246
            this.transformer = transformer;
1247
        }
1248

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

    
1262
        public XdmNode InitialContextNode
1263
        {
1264
            get {
1265
                JNodeInfo node = transformer.getInitialContextNode().getUnderlyingNode();
1266
                return node == null ? null : ((XdmNode)XdmValue.Wrap(node)); }
1267
            set { transformer.setInitialContextNode(value == null ? null : (net.sf.saxon.s9api.XdmNode)XdmValue.FromGroundedValueToJXdmValue(value.value)); }
1268
        }
1269

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

    
1292
        public void SetInputStream(Stream input, Uri baseUri)
1293
        {
1294
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
1295
            transformer.setSource(streamSource);
1296
        }
1297

    
1298
        /// <summary>
1299
		/// The initial mode for the stylesheet. This is either a <c>QName</c>, for a 
1300
        /// specific mode, or null, for the default mode.
1301
        /// </summary>
1302
        /// <remarks>
1303
        /// The default mode will usually be the unnamed mode, but if the stylesheet declares a
1304
        /// named mode as the default mode, then supplying null as the <c>InitialMode</c> invokes this default.
1305
        /// </remarks>
1306

    
1307
        public QName InitialMode
1308
        {
1309
            get
1310
            {
1311
                net.sf.saxon.s9api.QName mode = transformer.getInitialMode();
1312
                if (mode == null)
1313
                {
1314
                    return null;
1315
                }
1316

    
1317
                return QName.FromClarkName(mode.getClarkName());
1318
            }
1319
            set
1320
            {
1321
               transformer.setInitialMode(value == null ? null : net.sf.saxon.s9api.QName.fromEQName(value.EQName));
1322
            }
1323
        }
1324

    
1325

    
1326
        /// <summary>
1327
		/// The initial template for the stylesheet. This is either a <c>QName</c>, for a 
1328
        /// named template, or null, if no initial template has been set.
1329
        /// </summary>
1330
        /// <remarks>
1331
        /// If the stylesheet is to be invoked by calling the template named <c>xsl:initial-template</c>,
1332
		/// then the <c>InitialTemplate</c> property should be set to this <c>QName</c> explicitly.
1333
        /// </remarks>
1334
        /// <exception cref="DynamicError">Setting this property to the name of a template
1335
		/// that does not exist in the stylesheet throws a <c>DynamicError</c> with error 
1336
        /// code XTDE0040. Setting it to the name of a template that has template
1337
		/// parameters throws a <c>DynamicError</c> with error code XTDE0060.</exception>
1338

    
1339
        public QName InitialTemplate
1340
        {
1341
            get
1342
            {
1343
                return initialTemplateName;
1344
            }
1345
            set
1346
            {
1347
                initialTemplateName = value;
1348
                transformer.setInitialTemplate(initialTemplateName.UnderlyingQName());
1349
            }
1350
        }
1351

    
1352
        /// <summary>
1353
        /// The base output URI, which acts as the base URI for resolving the <c>href</c>
1354
        /// attribute of <c>xsl:result-document</c>.
1355
        /// </summary>
1356

    
1357
        public Uri BaseOutputUri
1358
        {
1359
            get
1360
            {
1361
                return new Uri(transformer.getBaseOutputURI());
1362
            }
1363
            set
1364
            {
1365
                transformer.setBaseOutputURI(value.ToString());
1366
            }
1367
        }
1368

    
1369

    
1370
        /// <summary>
1371
        /// The <c>SchemaValidationMode</c> to be used in this transformation, especially for documents
1372
        /// loaded using the <c>doc()</c>, <c>document()</c>, or <c>collection()</c> functions.
1373
        /// </summary>
1374

    
1375
        public SchemaValidationMode SchemaValidationMode
1376
        {
1377
            get
1378
            {
1379
                switch (transformer.getUnderlyingController().getSchemaValidationMode())
1380
                {
1381
                    case JValidation.STRICT:
1382
                        return SchemaValidationMode.Strict;
1383
                    case JValidation.LAX:
1384
                        return SchemaValidationMode.Lax;
1385
                    case JValidation.STRIP:
1386
                        return SchemaValidationMode.None;
1387
                    case JValidation.PRESERVE:
1388
                        return SchemaValidationMode.Preserve;
1389
                    case JValidation.DEFAULT:
1390
                    default:
1391
                        return SchemaValidationMode.Unspecified;
1392
                }
1393
            }
1394

    
1395
            set
1396
            {
1397
                switch (value)
1398
                {
1399
                    case SchemaValidationMode.Strict:
1400
                        transformer.setSchemaValidationMode(JValidationMode.STRICT);
1401
                        break;
1402
                    case SchemaValidationMode.Lax:
1403
                        transformer.setSchemaValidationMode(JValidationMode.LAX);
1404
                        break;
1405
                    case SchemaValidationMode.None:
1406
                        transformer.setSchemaValidationMode(JValidationMode.STRIP);
1407
                        break;
1408
                    case SchemaValidationMode.Preserve:
1409
                        transformer.setSchemaValidationMode(JValidationMode.PRESERVE);
1410
                        break;
1411
                    case SchemaValidationMode.Unspecified:
1412
                    default:
1413
                        transformer.setSchemaValidationMode(JValidationMode.DEFAULT);
1414
                        break;
1415
                }
1416
            }
1417
        }
1418

    
1419

    
1420

    
1421

    
1422

    
1423
        /// <summary>
1424
        /// The <c>XmlResolver</c> to be used at run-time to resolve and dereference URIs
1425
        /// supplied to the <c>doc()</c> and <c>document()</c> functions.
1426
        /// </summary>
1427

    
1428
        public XmlResolver InputXmlResolver
1429
        {
1430
            get
1431
            {
1432
                return ((JDotNetURIResolver)transformer.getURIResolver()).getXmlResolver();
1433
            }
1434
            set
1435
            {
1436
                transformer.setURIResolver(new JDotNetURIResolver(value));
1437
            }
1438
        }
1439

    
1440
        /// <summary>
1441
        /// The <c>IResultDocumentHandler</c> to be used at run-time to process the output
1442
        /// produced by any <c>xsl:result-document</c> instruction with an <c>href</c>
1443
        /// attribute.
1444
        /// </summary>
1445
        /// <remarks>
1446
        /// In the absence of a user-supplied result document handler, the <c>href</c>
1447
        /// attribute of the <c>xsl:result-document</c> instruction must be a valid relative
1448
        /// URI, which is resolved against the value of the <c>BaseOutputUri</c> property,
1449
        /// and the resulting absolute URI must identify a writable resource (typically
1450
        /// a file in filestore, using the <c>file:</c> URI scheme).
1451
        /// </remarks>
1452

    
1453
        public IResultDocumentHandler ResultDocumentHandler
1454
        {
1455
            get
1456
            {
1457
                return resultDocumentHandler;
1458
            }
1459
            set
1460
            {
1461
                resultDocumentHandler = value;
1462
                transformer.getUnderlyingController().setResultDocumentResolver(new ResultDocumentHandlerWrapper(value, transformer.getUnderlyingController().makePipelineConfiguration()));
1463
            }
1464
        }
1465

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

    
1484
        public IMessageListener MessageListener
1485
        {
1486
            set
1487
            {
1488
                messageListener = value;
1489
                transformer.setMessageListener(new MessageListenerProxy(value));
1490
            }
1491
            get
1492
            {
1493
                return messageListener;
1494
            }
1495
        }
1496

    
1497

    
1498

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

    
1519
        public IMessageListener2 MessageListener2
1520
        {
1521
            set
1522
            {
1523
                messageListener2 = value;
1524
                transformer.setMessageListener(new MessageListenerProxy2(value));
1525
            }
1526
            get
1527
            {
1528
                return messageListener2;
1529
            }
1530
        }
1531

    
1532
        /// <summary>
1533
        /// Destination for output of messages using the <c>trace()</c> function.
1534
        /// </summary>
1535
		/// <remarks> 
1536
		/// <para>If no message listener is supplied by the caller, message information will be written to
1537
		/// the standard error stream.</para>
1538
        /// <para>The supplied destination is ignored if a <c>TraceListener</c> is in use.</para>
1539
        /// </remarks>
1540

    
1541
        public StandardLogger TraceFunctionDestination
1542
        {
1543
            set
1544
            {
1545
                traceFunctionDestination = value;
1546
                transformer.setTraceFunctionDestination(value);
1547
            }
1548
            get
1549
            {
1550
                return traceFunctionDestination;
1551
            }
1552
        }
1553

    
1554

    
1555

    
1556
        /// <summary>
1557
        /// Set the value of a stylesheet parameter.
1558
        /// </summary>
1559
        /// <param name="name">The name of the parameter, expressed
1560
        /// as a QName. If a parameter of this name has been declared in the
1561
        /// stylesheet, the given value will be assigned to the variable. If the
1562
        /// variable has not been declared, calling this method has no effect (it is
1563
        /// not an error).</param>
1564
        /// <param name="value">The value to be given to the parameter.
1565
        /// If the parameter declaration defines a required type for the variable, then
1566
        /// this value will be converted in the same way as arguments to function calls
1567
        /// (for example, numeric promotion is applied).</param>
1568

    
1569
        public void SetParameter(QName name, XdmValue value)
1570
        {
1571
            transformer.setParameter(net.sf.saxon.s9api.QName.fromEQName(name.EQName), net.sf.saxon.s9api.XdmValue.wrap(value.value));
1572
        }
1573

    
1574
        public JDestination GetUnderlyingDestination() {
1575
            return transformer;
1576
        }
1577

    
1578

    
1579

    
1580
        /// <summary>
1581
		/// The destination for the result of the transformation. The class <c>XmlDestination</c> is an abstraction 
1582
        /// that allows a number of different kinds of destination to be specified.
1583
        /// </summary>
1584
        /// <remarks>
1585
        /// <para>The Destination can be used to chain transformations into a pipeline, by using one
1586
        /// <c>XsltTransformer</c> as the destination of another.</para>
1587
        /// </remarks>
1588

    
1589
        public XmlDestination Destination
1590
        {
1591
            get
1592
            {
1593
                return this.xmlDestination;
1594
            }
1595
            set
1596
            {
1597
                this.xmlDestination = value;
1598
                transformer.setDestination(value.GetUnderlyingDestination());
1599
            }
1600

    
1601
        }
1602

    
1603

    
1604
        /// <summary>
1605
		/// Close the <c>Destination</c>, releasing any resources that need to be released.
1606
        /// </summary>
1607
        /// <remarks>
1608
        /// This method is called by the system on completion of a query or transformation.
1609
		/// Some kinds of <c>Destination</c> may need to close an output stream, others might
1610
        /// not need to do anything. The default implementation does nothing.
1611
        /// </remarks>
1612

    
1613
        public void Close()
1614
        {
1615
            transformer.close();
1616

    
1617
        }
1618

    
1619
		// internal method
1620

    
1621
        internal JReceiver GetDestinationReceiver(XmlDestination destination)
1622
        {
1623

    
1624
            JController controller = transformer.getUnderlyingController();
1625
                JPipelineConfiguration pipe = controller.getConfiguration().makePipelineConfiguration();
1626
                JReceiver r = destination.GetUnderlyingDestination().getReceiver(pipe, controller.getExecutable().getPrimarySerializationProperties());
1627
                pipe.setController(controller);
1628
                return r;
1629
            //}
1630
        }
1631

    
1632
        /// <summary>
1633
        /// Run the transformation, sending the result to a specified destination.
1634
        /// </summary>
1635
        /// <param name="destination">
1636
        /// The destination for the results of the stylesheet. The class <c>XmlDestination</c>
1637
        /// is an abstraction that allows a number of different kinds of destination
1638
        /// to be specified.
1639
        /// </param>
1640
		/// <exception cref="DynamicError">Throws a <c>DynamicError</c> if the transformation
1641
        /// fails.</exception>
1642

    
1643
        public void Run(XmlDestination destination)
1644
        {
1645
            if (destination == null)
1646
            {
1647
                throw new DynamicError("Destination is null");
1648
            }
1649
           
1650
            try
1651
            {
1652
                transformer.setDestination(destination.GetUnderlyingDestination());
1653
                transformer.transform() ;
1654
               
1655
            }
1656
            catch (JSaxonApiException err)
1657
            {
1658
                throw new DynamicError(err);
1659
            }
1660
        }
1661

    
1662
        /*internal void applyTemplatesToSource(JStreamSource streamSource, JReceiver outi){
1663

    
1664
           
1665
            if (controller.getInitialMode().isDeclaredStreamable()) {
1666
                controller.applyStreamingTemplates(streamSource, outi);
1667
            }
1668
        } */
1669

    
1670
        /// <summary>
1671
        /// Escape hatch to the underlying Java implementation
1672
        /// </summary>
1673

    
1674
        public JController Implementation
1675
        {
1676
            get { return transformer.getUnderlyingController(); }
1677
        }
1678

    
1679

    
1680
    }
1681

    
1682
    /// <summary>
1683
	/// <c>RecoveryPolicy</c> is an enumeration of the different actions that can be taken when a "recoverable error" occurs.
1684
    /// </summary>  
1685

    
1686
    public enum RecoveryPolicy
1687
    {
1688
        /// <summary>
1689
        /// Ignore the error, take the recovery action, do not produce any message
1690
        /// </summary>
1691
        RecoverSilently,
1692

    
1693
        /// <summary>
1694
        /// Take the recovery action after outputting a warning message
1695
        /// </summary>
1696
        RecoverWithWarnings,
1697

    
1698
        /// <summary>
1699
        /// Treat the error as fatal
1700
        /// </summary>
1701
        DoNotRecover
1702

    
1703
    }
1704

    
1705

    
1706

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

    
1725
    public interface IResultDocumentHandler
1726
    {
1727

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

    
1754
    }
1755

    
1756
    ///<summary>Internal wrapper class for <c>IResultDocumentHandler</c></summary>
1757
    internal class ResultDocumentHandlerWrapper : JResultDocumentResolver
1758
    {
1759

    
1760
        private IResultDocumentHandler handler;
1761
        private ArrayList resultList = new ArrayList();
1762
        private ArrayList destinationList = new ArrayList();
1763
        private JPipelineConfiguration pipe;
1764

    
1765
        /// <summary>
1766
        /// Initializes a new instance of the <see cref="Saxon.Api.ResultDocumentHandlerWrapper"/> class.
1767
        /// </summary>
1768
        /// <param name="handler">Handler.</param>
1769
        /// <param name="pipe">Pipe.</param>
1770
        public ResultDocumentHandlerWrapper(IResultDocumentHandler handler, JPipelineConfiguration pipe)
1771
        {
1772
            this.handler = handler;
1773
            this.pipe = pipe;
1774
        }
1775

    
1776

    
1777

    
1778

    
1779
        /// <summary>
1780
        /// Close the specified result.
1781
        /// </summary>
1782
        /// <param name="result">Result.</param>
1783
        public void close(JResult result)
1784
        {
1785
            for (int i = 0; i < resultList.Count; i++)
1786
            {
1787
                if (Object.ReferenceEquals(resultList[i], result))
1788
                {
1789
                    ((XmlDestination)destinationList[i]).GetUnderlyingDestination().close();
1790
                    resultList.RemoveAt(i);
1791
                    destinationList.RemoveAt(i);
1792
                    return;
1793
                }
1794
            }
1795
        }
1796

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

    
1821
    /// <summary>An <c>IMessageListener</c> can be nominated to handle output
1822
    /// produced by the <c>xsl:message</c> instruction in an XSLT stylesheet.
1823
    /// </summary>
1824
    /// <remarks>
1825
    /// <para>This interface affects any <c>xsl:message</c> instruction
1826
    /// executed by the stylesheet.</para> 
1827
    /// <para>If no <c>IMessageListener</c> is nominated (in the
1828
    /// <c>MessageListener</c> property of the <c>XsltTransformer</c>), the output
1829
    /// of <code>xsl:message</code> is serialized, and is written to standard error
1830
    /// output stream.</para>
1831
    /// <para>If an <c>IMessageListener</c> is nominated, however, its
1832
    /// <c>Message</c> method will be called whenever an <c>xsl:message</c>
1833
    /// instruction is evaluated.</para> 
1834
    /// </remarks>
1835

    
1836
    public interface IMessageListener
1837
    {
1838

    
1839
        /// <summary>Handle the output of an <c>xsl:message</c> instruction
1840
        /// in the stylesheet
1841
        /// </summary>
1842
        /// <param name="content">a document node representing the message content. Note the putput of <c>xsl:message</c>
1843
        /// is always an XML document node. It can be flattened to obtain the stringvalue if required by calling
1844
        /// <c>GetStringValue()</c></param>
1845
        /// <param name="terminate">Set to true if <c>terminate ='yes'</c> was specified or to false otherwise</param>
1846
        /// <param name="location">an object that contains the location of the <c>xsl:message</c> This provides access to the URI of the stylesheet
1847
        /// module and the line number of the <c>xsl:message</c></param>
1848

    
1849
        /**public**/
1850
        void Message(XdmNode content, bool terminate, IXmlLocation location);
1851

    
1852
    }
1853

    
1854

    
1855

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

    
1873
    public interface IMessageListener2
1874
    {
1875

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

    
1887
        /**public**/
1888
        void Message(XdmNode content, QName errorCode,  bool terminate, IXmlLocation location);
1889

    
1890
    }
1891

    
1892
    /// <summary>
1893
    /// An <c>IXmlLocation</c> represents the location of a node within an XML document.
1894
    /// It is in two parts: the base URI (or system ID) of the external entity (which will usually
1895
    /// be the XML document entity itself), and the line number of a node relative
1896
    /// to the base URI of the containing external entity.
1897
    /// </summary>
1898

    
1899
    public interface IXmlLocation
1900
    {
1901

    
1902
        /// <summary>
1903
        /// The base URI (system ID) of an external entity within an XML document.
1904
        /// Set to null if the base URI is not known (for example, for an XML document
1905
        /// created programmatically where no base URI has been set up).
1906
        /// </summary>
1907

    
1908
        /**public**/
1909
        Uri BaseUri { get; set; }
1910

    
1911
        /// <summary>
1912
        /// The line number of a node relative to the start of the external entity.
1913
        /// The value -1 indicates that the line number is not known or not applicable.
1914
        /// </summary>
1915

    
1916
        /**public**/
1917
        int LineNumber { get; set; }
1918
    }
1919

    
1920

    
1921
    /// <summary>
1922
	/// Xml location. An implementation of <c>IXmlLocation</c>.
1923
    /// </summary>
1924
    internal class XmlLocation : IXmlLocation
1925
    {
1926
        private Uri baseUri;
1927
        private int lineNumber;
1928
        public Uri BaseUri
1929
        {
1930
            get { return baseUri; }
1931
            set { baseUri = value; }
1932
        }
1933
        public int LineNumber
1934
        {
1935
            get { return lineNumber; }
1936
            set { lineNumber = value; }
1937
        }
1938
    }
1939

    
1940

    
1941
    /// <summary>
1942
    /// Message listener proxy. This class implements a <c>net.sf.saxon.s9api.MessageListener</c> that can receive 
1943
    /// <c>xsl:message</c> output and send it to a user-supplied <c>MessageListener</c>
1944
    /// </summary>
1945
    [Serializable]
1946
    internal class MessageListenerProxy : net.sf.saxon.s9api.MessageListener
1947
    {
1948

    
1949
        public IMessageListener listener;
1950

    
1951
        /// <summary>
1952
        /// Initializes a new instance of the <see cref="Saxon.Api.MessageListenerProxy"/> class.
1953
        /// </summary>
1954
        /// <param name="ml">ml.</param>
1955
        public MessageListenerProxy(IMessageListener ml)
1956
        {
1957
            listener = ml;
1958
        }
1959

    
1960

    
1961
        public void message(net.sf.saxon.s9api.XdmNode xn, bool b, SourceLocator sl)
1962
        {
1963
            IXmlLocation location = new XmlLocation();
1964
            location.BaseUri = new Uri(sl.getSystemId());
1965
            location.LineNumber = sl.getLineNumber();
1966
            listener.Message((XdmNode)XdmValue.Wrap(xn.getUnderlyingValue()), b, location);
1967
        }
1968
    }
1969

    
1970

    
1971

    
1972
    /// <summary>
1973
	/// Message listener proxy. This class implements a <c>net.sf.saxon.s9api.MessageListener2</c> that can receive 
1974
	/// <c>xsl:message</c> output and send it to a user-supplied <c>MessageListener</c>
1975
    /// </summary>
1976
    [Serializable]
1977
    internal class MessageListenerProxy2 : net.sf.saxon.s9api.MessageListener2
1978
    {
1979

    
1980
        public IMessageListener2 listener;
1981

    
1982
        /// <summary>
1983
        /// Initializes a new instance of the <see cref="Saxon.Api.MessageListenerProxy"/> class.
1984
        /// </summary>
1985
        /// <param name="ml">ml.</param>
1986
        public MessageListenerProxy2(IMessageListener2 ml)
1987
        {
1988
            listener = ml;
1989
        }
1990

    
1991

    
1992
        public void message(net.sf.saxon.s9api.XdmNode xn, net.sf.saxon.s9api.QName qn, bool b, SourceLocator sl)
1993
        {
1994
            IXmlLocation location = new XmlLocation();
1995
            location.BaseUri = new Uri(sl.getSystemId());
1996
            location.LineNumber = sl.getLineNumber();
1997
            listener.Message((XdmNode)XdmValue.Wrap(xn.getUnderlyingValue()), new QName(qn),b, location);
1998
        }
1999
    }
2000

    
2001

    
2002

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

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

    
2017
    /// <para>An <code>Xslt30Transformer</code> is always constructed by running the <code>Load30</code>
2018
    /// method of an <see cref="XsltExecutable"/>.</para>
2019

    
2020
    /// <para>Unlike <code>XsltTransformer</code>, an <code>Xslt30Transformer</code> is not a <code>Destination</code>.
2021
    /// To pipe the results of one transformation into another, the target should be an <code>XsltTransfomer</code>
2022
    /// rather than an <code>Xslt30Transformer</code>.</para>
2023

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

    
2060
    [Serializable]
2061
    public class Xslt30Transformer
2062
    {
2063

    
2064

    
2065
        private IResultDocumentHandler resultDocumentHandler;
2066
        private StandardLogger traceFunctionDestination;
2067
        private IMessageListener messageListener;
2068
        private IMessageListener2 messageListener2;
2069
        private JXslt30Transformer transformer;
2070

    
2071
		// internal constructor
2072

    
2073
        internal Xslt30Transformer(JXslt30Transformer transformer)
2074
        {
2075

    
2076
            this.transformer = transformer;
2077
            //this.globalParameterSet = new GlobalParameterSet(globalParameters);
2078
        }
2079

    
2080

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

    
2084
        public XdmItem GlobalContextItem
2085
        {
2086
            set
2087
            {
2088
               transformer.setGlobalContextItem(value == null ? null : XdmItem.FromXdmItemItemToJXdmItem(value));
2089
            }
2090
         
2091
            get { return (XdmItem)XdmItem.Wrap(transformer.getUnderlyingController().getGlobalContextItem()); }
2092

    
2093
        }
2094

    
2095

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

    
2100
        public JXsltController GetUnderlyingController
2101
        {
2102
            get { return transformer.getUnderlyingController(); }
2103
        }
2104

    
2105
        internal JXslt30Transformer GetUnderlyingXslt30Transformer
2106
        {
2107
            get { return transformer; }
2108
        }
2109

    
2110

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

    
2140
            AbstractDestination localDestination = new AbstractDestination(this, finalDestination);
2141
            return localDestination;
2142
        }
2143

    
2144
		// internal method
2145
        internal JReceiver GetDestinationReceiver(XmlDestination destination)
2146
        {
2147
            JReceiver r = transformer.getDestinationReceiver(transformer.getUnderlyingController(), destination.GetUnderlyingDestination()); 
2148
            return r;
2149
        }
2150

    
2151

    
2152

    
2153
        /// <summary>
2154
        /// The <c>IResultDocumentHandler</c> to be used at run-time to process the output
2155
        /// produced by any <c>xsl:result-document</c> instruction with an <c>href</c>
2156
        /// attribute.
2157
        /// </summary>
2158
        /// <remarks>
2159
        /// In the absence of a user-supplied result document handler, the <c>href</c>
2160
        /// attribute of the <c>xsl:result-document</c> instruction must be a valid relative
2161
        /// URI, which is resolved against the value of the <c>BaseOutputUri</c> property,
2162
        /// and the resulting absolute URI must identify a writable resource (typically
2163
        /// a file in filestore, using the <c>file:</c> URI scheme).
2164
        /// </remarks>
2165

    
2166
        public IResultDocumentHandler ResultDocumentHandler
2167
        {
2168
            get
2169
            {
2170
                return resultDocumentHandler;
2171
            }
2172
            set
2173
            {
2174
                resultDocumentHandler = value;
2175
                transformer.getUnderlyingController().setResultDocumentResolver(new ResultDocumentHandlerWrapper(value, transformer.getUnderlyingController().makePipelineConfiguration()));
2176
            }
2177
        }
2178

    
2179
        /// <summary>
2180
        /// The <c>SchemaValidationMode</c> to be used in this transformation, especially for documents
2181
        /// loaded using the <code>doc()</code>, <code>document()</code>, or <code>collection()</code> functions.
2182
        /// </summary>
2183

    
2184
        public SchemaValidationMode SchemaValidationMode
2185
        {
2186
            get
2187
            {
2188
                switch (transformer.getUnderlyingController().getSchemaValidationMode())
2189
                {
2190
                    case JValidation.STRICT:
2191
                        return SchemaValidationMode.Strict;
2192
                    case JValidation.LAX:
2193
                        return SchemaValidationMode.Lax;
2194
                    case JValidation.STRIP:
2195
                        return SchemaValidationMode.None;
2196
                    case JValidation.PRESERVE:
2197
                        return SchemaValidationMode.Preserve;
2198
                    case JValidation.DEFAULT:
2199
                    default:
2200
                        return SchemaValidationMode.Unspecified;
2201
                }
2202
            }
2203

    
2204

    
2205
            set
2206
            {
2207
                switch (value)
2208
                {
2209
                    case SchemaValidationMode.Strict:
2210
                        transformer.setSchemaValidationMode(JValidationMode.STRICT);
2211
                        break;
2212
                    case SchemaValidationMode.Lax:
2213
                        transformer.setSchemaValidationMode(JValidationMode.LAX);
2214
                        break;
2215
                    case SchemaValidationMode.None:
2216
                        transformer.setSchemaValidationMode(JValidationMode.STRIP);
2217
                        break;
2218
                    case SchemaValidationMode.Preserve:
2219
                        transformer.setSchemaValidationMode(JValidationMode.PRESERVE);
2220
                        break;
2221
                    case SchemaValidationMode.Unspecified:
2222
                    default:
2223
                        transformer.setSchemaValidationMode(JValidationMode.DEFAULT);
2224
                        break;
2225
                }
2226
            }
2227
        }
2228

    
2229

    
2230

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

    
2250
            }
2251
            catch (net.sf.saxon.trans.XPathException e)
2252
            {
2253
                throw new StaticError(e);
2254
            }
2255

    
2256
        }
2257

    
2258

    
2259

    
2260
        /// <summary>Get the base output URI.</summary>
2261
        /// <remarks><para> This returns the value set using the setter method. If no value has been set
2262
        /// explicitly, then the method returns null if called before the transformation, or the computed
2263
        /// default base output URI if called after the transformation.
2264
        /// </para>
2265
        /// <para> The base output URI is used for resolving relative URIs in the <code>href</code> attribute
2266
        /// of the <code>xsl:result-document</code> instruction.</para></remarks>
2267
        /// <returns> The base output URI</returns>
2268

    
2269
        public String BaseOutputURI
2270
        {
2271
            set
2272
            {
2273
                transformer.setBaseOutputURI(value);
2274
            }
2275
            get { return transformer.getBaseOutputURI(); }
2276
        }
2277

    
2278
        /// <summary>
2279
        /// The <c>XmlResolver</c> to be used at run-time to resolve and dereference URIs
2280
        /// supplied to the <c>doc()</c> and <c>document()</c> functions.
2281
        /// </summary>
2282

    
2283
        public XmlResolver InputXmlResolver
2284
        {
2285
            get
2286
            {
2287
                return ((JDotNetURIResolver)transformer.getURIResolver()).getXmlResolver();
2288
            }
2289
            set
2290
            {
2291
                transformer.setURIResolver(new JDotNetURIResolver(value));
2292
            }
2293
        }
2294

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

    
2313

    
2314
        /// <summary>
2315
        /// Ask whether assertions (<c>xsl:assert</c> instructions) have been enabled at run time.
2316
        /// This property name has been misspelt, use <c>AssertionsEnabled</c> instead.
2317
        /// </summary>
2318
        [Obsolete("This property has been replaced by AssertionsEnabled.")]
2319
        public bool ssAssertionsEnabled
2320
        {
2321
            get
2322
            {
2323
                return transformer.isAssertionsEnabled();
2324
            }
2325
        }
2326

    
2327

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

    
2346
        public IMessageListener MessageListener
2347
        {
2348
            set
2349
            {
2350
                messageListener = value;
2351
                transformer.setMessageListener(new MessageListenerProxy(value));
2352
            }
2353
            get
2354
            {
2355
                return messageListener;
2356
            }
2357
        }
2358

    
2359

    
2360

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

    
2381
        public IMessageListener2 MessageListener2
2382
        {
2383
            set
2384
            {
2385
                messageListener2 = value;
2386
                transformer.setMessageListener(new MessageListenerProxy2(value));
2387
            }
2388
            get
2389
            {
2390
                return messageListener2;
2391
            }
2392
        }
2393

    
2394
        /// <summary>
2395
        /// Destination for output of messages using the <c>trace()</c> function. 
2396
        /// </summary>
2397
		/// <remarks>
2398
		/// <para>If no message listener is supplied by the caller, message information will be written to
2399
		/// the standard error stream.</para>
2400
        /// <para>The supplied destination is ignored if a <code>TraceListener</code> is in use.</para>
2401
        /// </remarks>
2402

    
2403
        public StandardLogger TraceFunctionDestination
2404
        {
2405
            set
2406
            {
2407
                traceFunctionDestination = value;
2408
                transformer.setTraceFunctionDestination(value);
2409
            }
2410
            get
2411
            {
2412
                return traceFunctionDestination;
2413
            }
2414
        }
2415

    
2416

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

    
2440
        /// <param name="parameters"> The parameters to be used for the initial template</param>
2441
        /// <param name="tunnel"> true if these values are to be used for setting tunnel parameters;
2442
        /// false if they are to be used for non-tunnel parameters</param>
2443
        
2444
        public void SetInitialTemplateParameters(Dictionary<QName, XdmValue> parameters, bool tunnel)
2445
        {
2446

    
2447
            JMap templateParameters = new java.util.HashMap();
2448
            foreach (KeyValuePair<QName, XdmValue> entry in parameters)
2449
            {
2450
                QName qname = entry.Key;
2451
                templateParameters.put(qname.UnderlyingQName(), XdmValue.FromGroundedValueToJXdmValue(entry.Value.value));
2452
            }
2453

    
2454
            transformer.setInitialTemplateParameters(templateParameters, tunnel);
2455

    
2456

    
2457
        }
2458

    
2459

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

    
2465
        public QName InitialMode
2466
        {
2467

    
2468
            set
2469
            {
2470
                try
2471
                {
2472
                    transformer.setInitialMode(value == null ? null : value.UnderlyingQName());
2473
                }
2474
                catch (net.sf.saxon.trans.XPathException e)
2475
                {
2476
                    throw new DynamicError(e);
2477
                }
2478
            }
2479
            get
2480
            {
2481
                net.sf.saxon.s9api.QName mode = transformer.getInitialMode();
2482
                if (mode == null)
2483
                    return null;
2484
                else
2485
                {
2486
                    return new QName(mode);
2487
                }
2488
            }
2489

    
2490

    
2491
        }
2492

    
2493

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

    
2506
        public void ApplyTemplates(Stream input, XmlDestination destination)
2507
        {
2508
            try
2509
            {
2510
                JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input));
2511
                transformer.applyTemplates(streamSource, destination.GetUnderlyingDestination());
2512
            
2513
            }
2514
            catch (JSaxonApiException exp)
2515
            {
2516
                throw new DynamicError(exp);
2517
            }
2518

    
2519
        }
2520

    
2521

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

    
2536
        public void ApplyTemplates(Stream input, Uri baseUri, XmlDestination destination)
2537
        {
2538
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2539
            try
2540
            {
2541
                transformer.applyTemplates(streamSource, destination.GetUnderlyingDestination());
2542
            }
2543
            catch (JSaxonApiException exp)
2544
            {
2545
                throw new DynamicError(exp.getMessage());
2546
            }
2547

    
2548
        }
2549

    
2550

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

    
2567
            try
2568
            {
2569
                transformer.transform(streamSource, destination.GetUnderlyingDestination());
2570
            }
2571
            catch (JSaxonApiException exp)
2572
            {
2573
                throw new DynamicError(exp.getMessage());
2574
            }
2575

    
2576
        }
2577

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

    
2605
        }
2606

    
2607

    
2608

    
2609

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

    
2623
        public XdmValue ApplyTemplates(Stream input, Uri baseUri)
2624
        {
2625
            JStreamSource streamSource = new JStreamSource(new JDotNetInputStream(input), Uri.EscapeUriString(baseUri.ToString()));
2626

    
2627
            try
2628
            {
2629
                net.sf.saxon.s9api.XdmValue value = transformer.applyTemplates(streamSource);
2630
                return XdmValue.Wrap(value.getUnderlyingValue());
2631

    
2632
            }
2633
            catch (JSaxonApiException exp)
2634
            {
2635
                throw new DynamicError(exp);
2636
            }
2637

    
2638
        }
2639

    
2640

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

    
2653
        public void ApplyTemplates(XdmValue selection, XmlDestination destination)
2654
        {
2655
            
2656
            try
2657
            {
2658
                transformer.applyTemplates(selection == null ? null : XdmValue.FromGroundedValueToJXdmValue(selection.value), destination.GetUnderlyingDestination());
2659
            }
2660
            catch (JSaxonApiException ex)
2661
            {
2662

    
2663
                throw new DynamicError(ex);
2664
            }
2665

    
2666
        }
2667

    
2668

    
2669

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

    
2681
        public XdmValue ApplyTemplates(XdmValue selection)
2682
        {
2683
           
2684
            try
2685
            {
2686
                return XdmValue.Wrap(transformer.applyTemplates(selection == null ? null : XdmValue.FromGroundedValueToJXdmValue(selection.value)).getUnderlyingValue());
2687
               
2688
            }
2689
            catch (JSaxonApiException ex)
2690
            {
2691

    
2692
                throw new DynamicError(ex);
2693
            }
2694

    
2695
        }
2696

    
2697

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

    
2711
        public void CallTemplate(QName templateName, XmlDestination destination)
2712
        {
2713
           
2714
            if (templateName == null)
2715
            {
2716
                templateName = new QName("xsl", NamespaceConstant.XSLT, "initial-template");
2717
            }
2718

    
2719
            try
2720
            {
2721
                transformer.callTemplate(templateName.UnderlyingQName(), destination.GetUnderlyingDestination());
2722
               
2723
            }
2724
            catch (JSaxonApiException exp)
2725
            {
2726
                throw new DynamicError(exp);
2727
            }
2728
        }
2729

    
2730

    
2731

    
2732
        /// <summary>
2733
        /// Invoke a transformation by calling a named template. The results of calling
2734
        /// the template are returned as a raw value, without wrapping in a document nnode
2735
        /// or serializing.
2736
        /// </summary>
2737
        /// <param name="templateName">The name of the initial template. This must match the name of a
2738
        /// public named template in the stylesheet. If the value is null, the QName <c>xsl:initial-template</c> is used.</param>
2739
        /// <returns>the raw results of the called template, without wrapping in a document node or serialization.</returns>
2740

    
2741
        public XdmValue CallTemplate(QName templateName)
2742
        {
2743
            if (templateName == null)
2744
            {
2745
                templateName = new QName("xsl", NamespaceConstant.XSLT, "initial-template");
2746
            }
2747

    
2748
            try
2749
            {
2750
                return XdmValue.Wrap(transformer.callTemplate(templateName.UnderlyingQName()).getUnderlyingValue());
2751
            }
2752
            catch (JSaxonApiException exp)
2753
            {
2754
                throw new DynamicError(exp);
2755
            }
2756
        }
2757

    
2758

    
2759
        /// <summary> Call a public user-defined function in the stylesheet. </summary>
2760
        /// <param name="function"> The name of the function to be called</param>
2761
        /// <param name="arguments">  The values of the arguments to be supplied to the function. These
2762
        /// will be converted if necessary to the type as defined in the function signature, using
2763
        /// the function conversion rules.</param>
2764
        /// <returns> the result of calling the function. This is the raw result, without wrapping in a document
2765
        /// node and without serialization.</returns>
2766

    
2767
        public XdmValue CallFunction(QName function, XdmValue[] arguments)
2768
        {
2769
            try
2770
            {
2771
                int len = arguments.Length;
2772
                net.sf.saxon.s9api.XdmValue[] values = new net.sf.saxon.s9api.XdmValue[len];
2773

    
2774
                for (int i=0; i<len; i++) {
2775
                    values[i] = XdmValue.FromGroundedValueToJXdmValue(arguments[i].value);
2776

    
2777
                }
2778

    
2779
                return XdmValue.Wrap(transformer.callFunction(function.UnderlyingQName(), values).getUnderlyingValue());
2780

    
2781
            }
2782
            catch (JSaxonApiException ex)
2783
            {
2784
                throw new DynamicError(ex);
2785

    
2786
            }
2787

    
2788
        }
2789

    
2790

    
2791

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

    
2803
        public void CallFunction(QName function, XdmValue[] arguments, XmlDestination destination)
2804
        {
2805

    
2806
            int len = arguments.Length;
2807
            net.sf.saxon.s9api.XdmValue[] values = new net.sf.saxon.s9api.XdmValue[len];
2808

    
2809
            for (int i = 0; i < len; i++)
2810
            {
2811
                values[i] = XdmValue.FromGroundedValueToJXdmValue(arguments[i].value);
2812

    
2813
            }
2814
            try
2815
            {
2816
                transformer.callFunction(function.UnderlyingQName(), values, destination.GetUnderlyingDestination());
2817

    
2818
            }
2819
            catch (JSaxonApiException ex) {
2820
                throw new DynamicError(ex);
2821
            }
2822
        }
2823

    
2824

    
2825
    }
2826

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

    
2830
    [Serializable]
2831
    public class XsltPackage
2832
    {
2833
        private JXsltPackage package;
2834
        private Processor processor;
2835
		// internal constructor: Initializes a new instance of the <see cref="Saxon.Api.XsltPackage"/> class.
2836
        internal XsltPackage(Processor p, JXsltPackage pp)
2837
        {
2838
            this.package = pp;
2839
            this.processor = p;
2840

    
2841
        }
2842

    
2843
        /// <summary>
2844
        /// Get the Processor from which this <c>XsltPackage</c> was constructed
2845
        /// </summary>
2846

    
2847
        public Processor Processor
2848
        {
2849
            get { return processor; }
2850
        }
2851

    
2852

    
2853
        /// <summary>
2854
        /// Get the name of the package (the URI appearing as the value of <code>xsl:package/@name</code>)
2855
        /// </summary>
2856
        /// <returns>The package name</returns>
2857

    
2858
        public String PackageName
2859
        {
2860
            get { return package.getName(); }
2861
        }
2862

    
2863

    
2864
        /// <summary>Get the version number of the package (the value of the attribute 
2865
		/// <code>xsl:package/@package-version</code></summary>
2866
        /// <returns>The package version number</returns>
2867

    
2868
        public String Version
2869
        {
2870
            get { return package.getVersion(); }
2871
        }
2872

    
2873

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

    
2879
        public XsltExecutable Link()
2880
        {
2881
            try
2882
            {
2883
                JXsltExecutable jexecutable = package.link();
2884
                XsltExecutable executable = new XsltExecutable(jexecutable);
2885
                executable.InternalProcessor = processor;
2886
                return executable;
2887
            }
2888
            catch (net.sf.saxon.trans.XPathException e)
2889
            {
2890
                throw new StaticError(e);
2891
            }
2892
        }
2893

    
2894
        /// <summary>Save this compiled package to filestore.</summary>
2895
        /// <param name="stream"> the stream to which the compiled package should be saved</param>
2896

    
2897
        public void Save(Stream stream)
2898
        {
2899
            JDotNetOutputStream outputStream = new JDotNetOutputStream(stream);
2900
            JExpressionPresenter outp = new JExpressionPresenter(package.getProcessor().getUnderlyingConfiguration(), new javax.xml.transform.stream.StreamResult(outputStream), true);
2901
            try
2902
            {
2903
                package.getUnderlyingPreparedPackage().export(outp);
2904
            }
2905
            catch (net.sf.saxon.trans.XPathException e)
2906
            {
2907
                throw new StaticError(e);
2908
            }
2909
        }
2910

    
2911

    
2912
        /// <summary>Escape-hatch interface to the underlying implementation class.</summary>
2913
		/// <returns>the underlying <c>StylesheetPackage</c>. The interface to <c>StylesheetPackage</c>
2914
        /// is not a stable part of the s9api API definition.</returns>
2915

    
2916
        public JStylesheetPackage getUnderlyingPreparedPackage()
2917
        {
2918
            return package.getUnderlyingPreparedPackage();
2919
        }
2920

    
2921
        internal JXsltPackage GetUnderlyingXsltPackage() {
2922
            return package;
2923
        }
2924
        
2925
    }
2926

    
2927

    
2928
}
2929

    
2930
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2931
// Copyright (c) 2020 Saxonica Limited.
2932
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
2933
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
2934
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
2935
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(13-13/13)