Project

Profile

Help

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

he / latest9.9 / hec / Saxon.C.API / SaxonProcessor.h @ 1117bc69

1
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright (c) 2019 Saxonica Limited.
3
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
6
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7

    
8
#ifndef SAXON_PROCESSOR_H
9
#define SAXON_PROCESSOR_H
10
        
11
#if defined __linux__ || defined __APPLE__
12
        #include <stdlib.h>
13
        #include <string.h>
14
        #include <dlfcn.h>
15

    
16
        #define HANDLE void*
17
        #define LoadLibrary(x) dlopen(x, RTLD_LAZY)
18
        #define GetProcAddress(x,y) dlsym(x,y)
19
#else
20
    #include <windows.h>
21
#endif
22

    
23
//#define DEBUG //remove
24
#define CVERSION "1.2.2"
25
#define CVERSION_API_NO 122
26
#include <string>
27
#include <iostream>
28
#include <sstream>  
29
#include <map>        
30
#include <vector>
31
#include <stdexcept>      // std::logic_error
32

    
33
#include "SaxonCGlue.h"
34
#include "SaxonCXPath.h"
35
#include "XsltProcessor.h"
36
#include "Xslt30Processor.h"
37
#include "XQueryProcessor.h"
38
#include "XPathProcessor.h"
39
#include "SchemaValidator.h"
40
//#include "com_saxonica_functions_extfn_PhpCall.h"
41
//#include "com_saxonica_functions_extfn_PhpCall_PhpFunctionCall.h"
42

    
43
class XsltProcessor;
44
class Xslt30Processor;
45
class XQueryProcessor;
46
class XPathProcessor;
47
class SchemaValidator;
48
class XdmValue;
49
class XdmNode;
50
class XdmItem;
51
class XdmAtomicValue;
52

    
53
#if CVERSION_API_NO >= 123
54
class XdmArray;
55
class XdmMap;
56
#endif
57

    
58

    
59

    
60
// The Saxon XSLT interface class
61

    
62
//std::mutex mtx;
63
/*! <code>MyException</code>. This struct captures details of the Java exception thrown from Saxon s9api API (Java).
64
 * <p/>
65
 */
66
typedef struct {
67
                std::string errorCode;
68
                std::string errorMessage;
69
                int linenumber;
70
                    bool isType;
71
                    bool isStatic;
72
                    bool isGlobal;
73
        }MyException;
74

    
75
typedef struct
76
{
77
    jobjectArray stringArray;
78
    jobjectArray objectArray;
79

    
80
}JParameters;
81

    
82

    
83
/*! <code>SaxonApiException</code>. An exception thrown by the Saxon s9api API (Java). This is always a C++ wrapper for some other underlying exception in Java
84
 * <p/>
85
 */
86
class SaxonApiException {
87

    
88
public:
89

    
90
    /**
91
     * A default Constructor. Create a SaxonApiException
92
     */
93
     SaxonApiException(){
94
        exceptions = std::vector<MyException>(0);
95
    }
96

    
97
    /**
98
     * A Copy constructor. Create a SaxonApiException
99
     * @param ex - The exception object to copy
100
     */
101
        SaxonApiException(const SaxonApiException &ex){
102
                exceptions = ex.exceptions;
103
        }
104

    
105
    /**
106
     * A constructor. Create a SaxonApiException
107
     * @param ec - The error code of the underlying exception thrown, if known
108
     * @param exM - The error message of the underlying exception thrown, if known
109
     */
110
        SaxonApiException(const char * ec, const char * exM){
111
                exceptions = std::vector<MyException>(0);
112
                MyException newEx;        
113
                if(ec != NULL){
114
                        newEx.errorCode =   std::string(ec);
115
                } else {
116
                        newEx.errorCode ="Unknown";        
117
                }
118
                if(exM != NULL){
119
                        newEx.errorMessage =  std::string(exM);
120
                } else {
121
                        newEx.errorMessage="Unkown";                
122
                }
123
                newEx.isType = false;
124
                    newEx.isStatic = false;
125
                    newEx.isGlobal = false;
126
                newEx.linenumber = 0;
127
                exceptions.push_back(newEx);
128
        }
129

    
130
    /**
131
     * A constructor. Create a SaxonApiException
132
     * @param ec - The error code of the underlying exception thrown, if known
133
     * @param exM - The error message of the underlying exception thrown, if known
134
     * @param typeErr - Flag indicating if the error is a type error
135
     * @param stat - Flag indicating a static error
136
     * @param glob - Flag for if the error is global
137
     * @param l - Line number information of where the error occurred
138
     */
139
        SaxonApiException(const char * ec, const char * exM, bool typeErr, bool stat, bool glob, int l){
140
                exceptions = std::vector<MyException>(20);
141
                MyException newEx;
142
                if(ec != NULL){
143
                        newEx.errorCode =   std::string(ec);
144
                } else {
145
                        newEx.errorCode ="ERROR1";        
146
                }
147
                if(exM != NULL){
148
                        newEx.errorMessage =  std::string(exM);
149
                } else {
150
                        newEx.errorMessage="ERROR2";                
151
                }
152
                newEx.isType = typeErr;
153
                    newEx.isStatic = stat;
154
                    newEx.isGlobal = glob;
155
                newEx.linenumber = l;
156
                exceptions.push_back(newEx);
157
        }
158

    
159
    /**
160
     * Creates a SaxonApiException and adds it to a vector of exceptions
161
     * @param ec - The error code of the underlying exception thrown, if known
162
     * @param exM - The error message of the underlying exception thrown, if known
163
     * @param typeErr - Flag indicating if the error is a type error
164
     * @param stat - Flag indicating a static error
165
     * @param glob - Flag for if the error is global
166
     * @param l - Line number information of where the error occurred
167
     */
168
        void add(const char * ec, const char * exM, bool typeErr, bool stat, bool glob, int l){
169
                MyException newEx;
170
                if(ec != NULL){
171
                        newEx.errorCode =   std::string(ec);
172
                } else {
173
                        newEx.errorCode ="ERROR1";        
174
                }
175
                if(exM != NULL){
176
                        newEx.errorMessage =  std::string(exM);
177
                } else {
178
                        newEx.errorMessage="ERROR2";                
179
                }
180
                newEx.isType = typeErr;
181
                    newEx.isStatic = stat;
182
                    newEx.isGlobal = glob;
183
                newEx.linenumber = l;
184
                exceptions.push_back(newEx);
185
        }
186

    
187

    
188
    /**
189
     * A destructor.
190
     */
191
        ~SaxonApiException(){ 
192
          clear();
193
        }
194

    
195
    /**
196
     * Get the error code associated with the ith exception in the vector, if there is one
197
     * @param i - ith exception in the vector
198
     * @return the associated error code, or null if no error code is available
199
     */
200
        const char * getErrorCode(int i){
201
                if((size_t)i <= exceptions.size()){
202
                        return exceptions[i].errorCode.c_str();
203
                }
204
                return NULL;
205
        }
206

    
207

    
208
        int getLineNumber(int i){
209
                if((size_t)i <= exceptions.size()){
210
                        return exceptions[i].linenumber;        
211
                }
212
                return 0;
213
        }
214

    
215
        bool isGlobalError(int i){
216
                if((size_t)i <= exceptions.size()){
217
                        return exceptions[i].isGlobal;
218
                }
219
                return false;
220
        }
221

    
222
        bool isStaticError(int i){
223
                if((size_t)i <= exceptions.size()){
224
                        return exceptions[i].isStatic;
225
                }
226
                return false;
227
        }
228

    
229
        bool isTypeError(int i){
230
                if((size_t) i <= exceptions.size()){
231
                        return exceptions[i].isType;
232
                }
233
                return false;
234
        }
235

    
236
        void clear(){
237
          for(size_t i =0; i< exceptions.size();i++) {
238
                exceptions[i].errorCode.clear();
239
                exceptions[i].errorMessage.clear();        
240
          }
241
          exceptions.clear();
242
        }
243

    
244
        int count(){
245
                return (int)exceptions.size();        
246
        }
247

    
248
    /**
249
     * Returns the detail message string of the ith throwable, if there is one
250
     * @param i - ith exception in the vector
251
     * @return the detail message string of this <tt>Throwable</tt> instance
252
     *         (which may be <tt>null</tt>).
253
     */
254
        const char * getErrorMessage(int i){
255
                if((size_t)i <= exceptions.size()){
256
                        return exceptions[i].errorMessage.c_str();
257
                }
258
                return NULL;
259
        }
260

    
261
        const char * getErrorMessages(){
262
                std::string result;
263
                for(size_t i = 0;i<exceptions.size();i++) {
264
                        result += getErrorMessage(i);
265
                }
266
                if(result.empty()) { return NULL;}
267
                return result.c_str();
268
        }
269

    
270
    /**
271
     * Returns the ith Exception added, if there is one
272
     * @param i - ith exception in the vector
273
     * @return MyException
274
     */
275
        MyException getException(int i){
276
                if((size_t)i <= exceptions.size()){
277
                        return exceptions[i];        
278
                }
279
                throw 0;
280
        }
281

    
282
        
283

    
284
private:
285
        std::vector<MyException> exceptions; /*!< Capture exceptions in a std:vector */
286
};
287

    
288

    
289

    
290

    
291

    
292

    
293

    
294

    
295
//==========================================
296

    
297

    
298

    
299
/*! An <code>SaxonProcessor</code> acts as a factory for generating XQuery, XPath, Schema and XSLT compilers
300
 */
301
class SaxonProcessor {
302
friend class XsltProcessor;
303
friend class Xslt30Processor;
304
friend class XQueryProcessor;
305
friend class SchemaValidator;
306
friend class XPathProcessor;
307
friend class XdmValue;
308
friend class XdmAtomicValue;
309

    
310
public:
311

    
312
   //! A default constructor.
313
    /*!
314
      * Create Saxon Processor.
315
    */
316

    
317
    SaxonProcessor();
318

    
319
   //! constructor based upon a Saxon configuration file.
320
    /*!
321
      * Create Saxon Processor.
322
    */
323

    
324
    SaxonProcessor(const char * configFile);
325

    
326

    
327
   //! A constructor.
328
    /*!
329
      * Create Saxon Processor.
330
      * @param l - Flag that a license is to be used. Default is false.        
331
    */
332
    SaxonProcessor(bool l);
333

    
334
    SaxonProcessor& operator=( const SaxonProcessor& other );
335

    
336

    
337
        /**
338
         * Xslt30Processor copy constructor.
339
         * @param other - Xslt30Processor
340
         */
341
    SaxonProcessor(const SaxonProcessor &other);
342

    
343
   /*!
344

345
      * Destructor
346
    */
347
    ~SaxonProcessor();
348

    
349

    
350
   //! Get the Processor object. Method used in Python
351
   /* SaxonProcessor * getProcessor(){
352
        return this;
353
    }*/
354
        
355
   /*!
356

357
      * Create an XsltProcessor. An XsltProcessor is used to compile XSLT stylesheets.
358
      * @return a newly created XsltProcessor        
359
    */        
360
    XsltProcessor * newXsltProcessor();
361

    
362
   /*!
363

364
      * Create an Xslt30Processor. An Xslt30Processor is used to compile XSLT30 stylesheets.
365
      * @return a newly created Xslt30Processor        
366
    */        
367
    Xslt30Processor * newXslt30Processor();
368

    
369

    
370
    /*!
371
     * Create an XQueryProcessor. An XQueryProcessor is used to compile XQuery queries.
372
     *
373
     * @return a newly created XQueryProcessor
374
     */
375
    XQueryProcessor * newXQueryProcessor();
376

    
377

    
378
    /*!
379
     * Create an XPathProcessor. An XPathProcessor is used to compile XPath expressions.
380
     *
381
     * @return a newly created XPathProcessor
382
     */
383
    XPathProcessor * newXPathProcessor();
384

    
385
    /*!
386
     * Create a SchemaValidator which can be used to validate instance documents against the schema held by this
387
     * SchemaManager
388
     *
389
     * @return a new SchemaValidator
390
     */
391
    SchemaValidator * newSchemaValidator();
392

    
393

    
394
    /*!
395
     * Factory method. Unlike the constructor, this avoids creating a new StringValue in the case
396
     * of a zero-length string (and potentially other strings, in future)
397
     *
398
     * @param value the String value. Null is taken as equivalent to "".
399
     * @return the corresponding StringValue
400
     */
401
    XdmAtomicValue * makeStringValue(std::string str);
402

    
403
    /*!
404
     * Factory method. Unlike the constructor, this avoids creating a new StringValue in the case
405
     * of a zero-length string (and potentially other strings, in future)
406
     *
407
     * @param value the char pointer array. Null is taken as equivalent to "".
408
     * @return the corresponding StringValue
409
     */
410
    XdmAtomicValue * makeStringValue(const char * str);
411

    
412
    /*!
413
     * Factory method: makes either an Int64Value or a BigIntegerValue depending on the value supplied
414
     *
415
     * @param i the supplied primitive integer value
416
     * @return the value as a XdmAtomicValue which is a BigIntegerValue or Int64Value as appropriate
417
     */
418
    XdmAtomicValue * makeIntegerValue(int i);
419

    
420

    
421
    /*!
422
     * Factory method (for convenience in compiled bytecode)
423
     *
424
     * @param d the value of the double
425
     * @return a new XdmAtomicValue
426
     */
427
    XdmAtomicValue * makeDoubleValue(double d);
428

    
429
    /*!
430
     * Factory method (for convenience in compiled bytecode)
431
     *
432
     * @param f the value of the foat
433
     * @return a new XdmAtomicValue
434
     */
435
    XdmAtomicValue * makeFloatValue(float);
436

    
437
    /*!
438
     * Factory method: makes either an Int64Value or a BigIntegerValue depending on the value supplied
439
     *
440
     * @param l the supplied primitive long value
441
     * @return the value as a XdmAtomicValue which is a BigIntegerValue or Int64Value as appropriate
442
     */
443
    XdmAtomicValue * makeLongValue(long l);
444

    
445
    /*!
446
     * Factory method: makes a XdmAtomicValue representing a boolean Value
447
     *
448
     * @param b true or false, to determine which boolean value is
449
     *              required
450
     * @return the XdmAtomicValue requested
451
     */
452
    XdmAtomicValue * makeBooleanValue(bool b);
453

    
454
    /**
455
     * Create an QName Xdm value from string representation in clark notation
456
     * @param str - The value given in a string form in clark notation. {uri}local
457
     * @return XdmAtomicValue - value
458
    */
459
    XdmAtomicValue * makeQNameValue(const char * str);
460

    
461
    /*!
462
     * Create an Xdm Atomic value from string representation
463
     * @param type    - Local name of a type in the XML Schema namespace.
464
     * @param value - The value given in a string form.
465
     * In the case of a QName the value supplied must be in clark notation. {uri}local
466
     * @return XdmValue - value
467
    */
468
    XdmAtomicValue * makeAtomicValue(const char * type, const char * value);
469

    
470
#if CVERSION_API_NO >= 123
471
    /**
472
        * Make an XdmArray whose members are from string representation
473
        * @param input the input array of booleans
474
        * @return an XdmArray whose members are xs:boolean values corresponding one-to-one with the input
475
   */
476
    XdmArray * makeArray(const char ** input, int length);
477

    
478

    
479
    /**
480
        * Make an XdmArray whose members are xs:short values
481
        * @param input the input array of booleans
482
        * @return an XdmArray whose members are xs:boolean values corresponding one-to-one with the input
483
   */
484
    XdmArray * makeArray(short * input, int length);
485

    
486

    
487

    
488
    /**
489
        * Make an XdmArray whose members are xs:int values
490
        * @param input the input array of booleans
491
        * @return an XdmArray whose members are xs:boolean values corresponding one-to-one with the input
492
   */
493
    XdmArray * makeArray(int * input, int length);
494

    
495
    /**
496
        * Make an XdmArray whose members are xs:long values
497
        * @param input the input array of booleans
498
        * @return an XdmArray whose members are xs:boolean values corresponding one-to-one with the input
499
   */
500
    XdmArray * makeArray(long * input, int length);
501

    
502
    /**
503
        * Make an XdmArray whose members are xs:boolean values
504
        * @param input the input array of booleans
505
        * @return an XdmArray whose members are xs:boolean values corresponding one-to-one with the input
506
   */
507
    XdmArray * makeArray(bool * input, int length);
508
    
509

    
510
#endif
511

    
512
     /**
513
     * Get the string representation of the XdmValue.
514
     * @return char array
515
     */
516
    const char * getStringValue(XdmItem * item);
517

    
518
    /**
519
     * Parse a lexical representation of the source document and return it as an XdmNode
520
    */
521
    XdmNode * parseXmlFromString(const char* source);
522

    
523
    /**
524
     * Parse a source document file and return it as an XdmNode.
525
    */
526
    XdmNode * parseXmlFromFile(const char* source);
527

    
528
    /**
529
     * Parse a source document available by URI and return it as an XdmNode.
530
    */
531
    XdmNode * parseXmlFromUri(const char* source);
532

    
533
    int getNodeKind(jobject);
534

    
535
    bool isSchemaAwareProcessor();
536

    
537
 
538

    
539
    /**
540
     * Checks for pending exceptions without creating a local reference to the exception object
541
     * @return bool - true when there is a pending exception; otherwise return false
542
    */
543
    bool exceptionOccurred();
544

    
545
    /**
546

547
     * Clears any exception that is currently being thrown. If no exception is currently being thrown, this routine has no effect.
548
    */
549
    void exceptionClear(bool clearCPPException=true);
550

    
551
    /**
552
     * Checks for pending exceptions and creates a SaxonApiException object, which handles one or more local exceptions objects
553
     * @param env
554
     * @param callingClass
555
     * @param callingObject
556
     * @return SaxonApiException
557
    */
558
    SaxonApiException * checkForExceptionCPP(JNIEnv* env, jclass callingClass,  jobject callingObject);
559

    
560
    SaxonApiException * getException();
561

    
562
    /*
563
      * Clean up and destroy Java VM to release memory used. 
564
     */
565
    static void release();
566

    
567

    
568
    /**
569
     * set the current working directory
570
    */
571
   void setcwd(const char* cwd);
572

    
573
    /**
574
     * get the current working directory
575
    */
576
   const char* getcwd();
577

    
578

    
579
    /**
580
     * set saxon resources directory
581
    */
582
   void setResourcesDirectory(const char* dir);
583
        
584
    /**
585
     * set catalog to be used in Saxon
586
    */
587
   void setCatalog(const char* catalogFile, bool isTracing);
588

    
589
    /**
590
     * get saxon resources directory
591
    */
592
   const char * getResourcesDirectory();
593

    
594
    /**
595
     * Set a configuration property specific to the processor in use. 
596
     * Properties specified here are common across all the processors.
597
     * Example 'l':enable line number has the value 'on' or 'off'
598
     * @param name of the property
599
     * @param value of the property
600
     */
601
    void setConfigurationProperty(const char * name, const char * value);
602

    
603
    /**
604
     * Clear configuration properties specific to the processor in use. 
605
     */
606
     void clearConfigurationProperties();
607

    
608

    
609
    /**
610
     * Get the Saxon version
611
     * @return char array
612
     */
613
    const char * version();
614

    
615
/*
616
     * Add a native method.
617
     * @param name of the native method
618
     * @param signature of the native method
619
     * @param fnPtr Pointer to the native method
620
 */
621
void addNativeMethod(char *name, char* signature, void * fnPtr){
622

    
623
        JNINativeMethod method;
624
        method.name = name;
625
        method.signature = signature;
626
        method.fnPtr = fnPtr;
627

    
628
        nativeMethodVect.push_back(method);
629

    
630
        
631

    
632
}
633

    
634
/*
635
     * Register several native methods for one class.
636
     * @param libName name of the library which contains the function(s). Loads the library
637
     * @param gMethods Register native methods. Default is NULL, also NULL allowed in which cause assumption is made the user has added native methods using the method addNativeMethod .
638
 * @return bool success of registered native method
639
 */
640
bool registerCPPFunction(char * libName, JNINativeMethod * gMethods=NULL){
641
        if(libName != NULL) {
642
                setConfigurationProperty("extc", libName);
643
                        
644
        }
645

    
646
        if(gMethods == NULL && nativeMethodVect.size()==0) {
647
        return false;
648
        } else {
649
                if(gMethods == NULL) {
650
                        //copy vector to gMethods
651
                        gMethods = new JNINativeMethod[nativeMethodVect.size()];
652
                } 
653
                return registerNativeMethods(sxn_environ->env, "com/saxonica/functions/extfn/CppCall$PhpFunctionCall",
654
    gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
655
        
656

    
657
        }
658
        return false;
659
}
660

    
661
/*
662
 * Register several native methods for one class.
663
 * @return bool success of registered native method
664
 */
665
static bool registerNativeMethods(JNIEnv* env, const char* className,
666
    JNINativeMethod* gMethods, int numMethods)
667
{
668
    jclass clazz;
669
    clazz = env->FindClass(className);
670
    if (clazz == NULL) {
671
        std::cerr<<"Native registration unable to find class "<< className<<std::endl;
672
        return false;
673
    }
674
        
675
    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
676
       // std::cerr<<"RegisterNatives failed for "<< className<<std::endl;
677
        return false;
678
    }
679
    return true;
680
}
681

    
682

    
683
        /* TODO: Remove use of this method.*/
684
        const char* checkException(jobject cpp);
685

    
686
        /* Internal use*/
687
        void checkAndCreateException(jclass cppClass);
688

    
689

    
690

    
691
//        XPathEngine
692
//        XQueryEngine
693
//        SchemaManager
694

    
695
   // static JNIEnv *env;
696
    static int jvmCreatedCPP;
697
    static sxnc_environment * sxn_environ;
698
    static int refCount;
699
    std::string cwd; /*!< current working directory */
700
    jobject proc; /*!< Java Processor object */
701
    
702
    /*static JavaVM *jvm;*/
703
    
704
protected:
705

    
706

    
707

    
708
        jclass xdmAtomicClass;
709
        jclass  versionClass;
710
        jclass  procClass;
711
        jclass  saxonCAPIClass;
712
        std::string cwdV; /*!< current working directory */
713
        //std::string resources_dir; /*!< current Saxon resources directory */
714
        char * versionStr;
715
        std::map<std::string,XdmValue*> parameters; /*!< map of parameters used for the transformation as (string, value) pairs */
716
        std::map<std::string,std::string> configProperties; /*!< map of properties used for the transformation as (string, string) pairs */         
717
        bool licensei; /*!< indicates whether the Processor requires a Saxon that needs a license file (i.e. Saxon-EE) other a Saxon-HE Processor is created  */
718
        bool closed;
719
        SaxonApiException* exception; /*!< Pointer to any potential exception thrown */
720

    
721
        JNINativeMethod * nativeMethods;
722
        std::vector<JNINativeMethod> nativeMethodVect; /*!< Vector of native methods defined by user */
723

    
724

    
725

    
726
private:
727

    
728
    
729

    
730
        void applyConfigurationProperties();
731
        // Saxon/C method for internal use
732
    static JParameters createParameterJArray(std::map<std::string,XdmValue*> parameters, std::map<std::string,std::string> properties);
733
    static jobjectArray createJArray(XdmValue ** values, int length);
734
};
735

    
736
//===============================================================================================
737

    
738
#endif /* SAXON_PROCESSOR_H */
(12-12/50)