Project

Profile

Help

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

he / src / main / c / Saxon.C.API / SaxonProcessor.cpp @ 55b80284

1
#ifndef __linux__
2
#ifndef __APPLE__
3
//#include "stdafx.h"
4
#include <Tchar.h>
5
#endif
6
#endif
7

    
8
#include "SaxonProcessor.h"
9
#include "XdmValue.h"
10
#include "XdmItem.h"
11
#include "XdmNode.h"
12
#include "XdmFunctionItem.h"
13
#include "XdmMap.h"
14
#include "XdmArray.h"
15
#include "XdmAtomicValue.h"
16

    
17

    
18
//#define DEBUG
19
#ifdef DEBUG
20
#include <signal.h>
21
#endif
22

    
23
#include <stdio.h>
24

    
25

    
26
#if defined MEM_DEBUG
27

    
28
void* newImpl(std::size_t sz,char const* file, int line){
29
    static int counter{};
30
    void* ptr= std::malloc(sz);
31
    std::cerr << "Saxon/C Mem test: "<<file << ": " << line << " " <<  ptr << std::endl;
32
    myAlloc.push_back(ptr);
33
    return ptr;
34
}
35

    
36
void* operator new(std::size_t sz,char const* file, int line){
37
return newImpl(sz,file,line);
38
}
39

    
40
void* operator new [](std::size_t sz,char const* file, int line){
41
return newImpl(sz,file,line);
42
}
43

    
44
void operator delete(void* ptr) noexcept{
45
    auto ind= std::distance(myAlloc.begin(),std::find(myAlloc.begin(), myAlloc.end(),ptr));
46
    myAlloc[ind]= nullptr;
47
    std::free(ptr);
48
}
49

    
50
#define new new(__FILE__, __LINE__)
51

    
52
void SaxonProcessor::getInfo(){
53

    
54
    std::cout << std::endl;
55

    
56
    std::cout << "Allocation: " << std::endl;
57
    for (auto i: myAlloc){
58
        if (i != nullptr ) std::cout << " " << i << std::endl;
59
    }
60

    
61
    std::cout << std::endl;
62

    
63
}
64

    
65
#endif
66

    
67
//jobject cpp;
68
const char *failure;
69
sxnc_environment *SaxonProcessor::sxn_environ = 0;
70
int SaxonProcessor::jvmCreatedCPP = 0;
71

    
72
bool SaxonProcessor::exceptionOccurred() {
73
    return SaxonProcessor::sxn_environ->env->ExceptionCheck() || exception != nullptr;
74
}
75

    
76
const char *SaxonProcessor::checkException() {
77
    const char *message = nullptr;
78
    message = checkForException(sxn_environ);
79
    return message;
80
}
81

    
82

    
83

    
84
SaxonApiException *SaxonProcessor::checkAndCreateException(jclass cppClass) {
85
    if (SaxonProcessor::sxn_environ->env->ExceptionCheck()) {
86
        SaxonApiException *exception = checkForExceptionCPP(SaxonProcessor::sxn_environ->env, cppClass, nullptr);
87
#ifdef DEBUG
88
        SaxonProcessor::sxn_environ->env->ExceptionDescribe();
89
#endif
90
        return exception;
91
    }
92
    return nullptr;
93
}
94

    
95
const char *SaxonProcessor::getErrorMessage() {
96
    if(exception == nullptr) {
97
        exception =  SaxonProcessor::checkForExceptionCPP(SaxonProcessor::sxn_environ->env,
98
                                                                            saxonCAPIClass,nullptr);
99
    }
100
    if (exception == nullptr) { return nullptr; }
101
    return exception->getMessage();
102
}
103

    
104
void SaxonProcessor::exceptionClear() {
105
    if(exceptionOccurred()) {
106
        SaxonProcessor::sxn_environ->env->ExceptionClear();
107
    }
108
    if (exception != nullptr) {
109
        std::cerr<< "saxonProc exception= "<< exception <<std::endl;
110
        delete exception;
111
        exception = nullptr;
112
    }
113

    
114
}
115

    
116

    
117
SaxonProcessor::SaxonProcessor() {
118
    licensei = false;
119
    SaxonProcessor(false);
120
}
121

    
122
const char * SaxonProcessor::getResourcesDirectory() {
123
    return NULL;
124
}
125

    
126
void SaxonProcessor::createException(const char * message) {
127

    
128
    exceptionClear();
129

    
130
    if(message == nullptr) {
131
        exception = checkAndCreateException(saxonCAPIClass);
132
    } else {
133
        exception = new SaxonApiException(message);
134
    }
135

    
136
}
137

    
138

    
139
SaxonApiException * SaxonProcessor::checkForExceptionCPP(JNIEnv *env, jclass callingClass, jobject callingObject) {
140

    
141
    if (env->ExceptionCheck()) {
142
        std::string result1 = "";
143
        std::string errorCode = "";
144
        jthrowable exc = env->ExceptionOccurred();
145

    
146
#ifdef DEBUG
147
        env->ExceptionDescribe();
148
#endif
149
        jclass exccls(env->GetObjectClass(exc));
150
        jclass clscls(env->FindClass("java/lang/Class"));
151

    
152
        jmethodID getName(env->GetMethodID(clscls, "getName", "()Ljava/lang/String;"));
153
        jstring name(static_cast<jstring>(env->CallObjectMethod(exccls, getName)));
154
        char const *utfName(env->GetStringUTFChars(name, 0));
155
        result1 = (std::string(utfName));
156
        env->ReleaseStringUTFChars(name, utfName);
157

    
158
        jmethodID getMessage(env->GetMethodID(exccls, "getMessage", "()Ljava/lang/String;"));
159
        if (getMessage) {
160

    
161
            jstring message((jstring) (env->CallObjectMethod(exc, getMessage)));
162
            char const *utfMessage = nullptr;
163
            if (!message) {
164
                utfMessage = "";
165
                return nullptr;
166
            } else {
167
                utfMessage = (env->GetStringUTFChars(message, 0));
168
            }
169
            if (utfMessage != nullptr) {
170
                result1 = (result1 + " : ") + utfMessage;
171
            }
172

    
173
            env->ReleaseStringUTFChars(message, utfMessage);
174

    
175
            if (callingObject != nullptr && result1.compare(0, 43, "net.sf.saxon.s9api.SaxonApiException", 43) == 0) {
176

    
177
                jclass saxonApiExceptionClass(env->FindClass("net/sf/saxon/s9api/SaxonApiException"));
178
                static jmethodID lineNumID = nullptr;
179
                if (lineNumID == nullptr) {
180
                    lineNumID = env->GetMethodID(saxonApiExceptionClass, "getLinenumber", "()I");
181
                }
182
                static jmethodID ecID = nullptr;
183
                if (ecID == nullptr) {
184
                    ecID = env->GetMethodID(saxonApiExceptionClass, "getErrorCode", "()Ljnet/sf/saxon/s9api/QName;");
185
                }
186
                static jmethodID esysID = nullptr;
187
                if (esysID == nullptr) {
188
                    esysID = env->GetMethodID(saxonApiExceptionClass, "getSystemId", "()Ljava/lang/String;");
189
                }
190

    
191

    
192
                jobject errCodeQName = (jobject) (env->CallObjectMethod(exc, ecID));
193
                jstring errSystemID = (jstring) (env->CallObjectMethod(exc, esysID));
194
                int linenum = env->CallIntMethod(exc, lineNumID);
195

    
196
                jclass qnameClass(env->FindClass("net/sf/saxon/s9api/QName"));
197
                static jmethodID qnameStrID = nullptr;
198
                if (qnameStrID == nullptr) {
199
                    qnameStrID = env->GetMethodID(qnameClass, "toString", "()Ljava/lang/String;");
200
                }
201

    
202
                jstring qnameStr = (jstring) (env->CallObjectMethod(errCodeQName, qnameStrID));
203

    
204

    
205
                SaxonApiException *saxonExceptions = new SaxonApiException(result1.c_str(),
206
                                                                           (qnameStr ? env->GetStringUTFChars(qnameStr,
207
                                                                                                              0)
208
                                                                                     : nullptr),
209
                                                                           (errSystemID ? env->GetStringUTFChars(
210
                                                                                   errSystemID, 0) : nullptr), linenum);
211

    
212
                if (errCodeQName) {
213
                    env->DeleteLocalRef(errCodeQName);
214
                }
215
                if (errSystemID) {
216
                    env->DeleteLocalRef(errSystemID);
217
                }
218
                if (qnameStr) {
219
                    env->DeleteLocalRef(qnameStr);
220
                }
221

    
222
                if (message) {
223
                    env->DeleteLocalRef(message);
224
                }
225
                env->ExceptionClear();
226
                return saxonExceptions;
227
            }
228
        }
229
        SaxonApiException *saxonExceptions = new SaxonApiException(result1.c_str());
230
        //env->ExceptionDescribe();
231
        env->ExceptionClear();
232
        return saxonExceptions;
233
    }
234
    return nullptr;
235

    
236
}
237

    
238

    
239
SaxonProcessor::SaxonProcessor(bool l) {
240

    
241
    cwd = "";
242
    licensei = l;
243
    versionStr = nullptr;
244

    
245
    if (SaxonProcessor::jvmCreatedCPP == 0) {
246
        SaxonProcessor::jvmCreatedCPP = 1;
247
        SaxonProcessor::sxn_environ = new sxnc_environment;//(sxnc_environment *)malloc(sizeof(sxnc_environment));
248

    
249

    
250
        /*
251
         * First of all, load required component.
252
         * By the time of JET initialization, all components should be loaded.
253
         */
254

    
255
        SaxonProcessor::sxn_environ->myDllHandle = loadDefaultDll();
256

    
257
        /*
258
         * Initialize JET run-time.
259
         * The handle of loaded component is used to retrieve Invocation API.
260
         */
261
        initDefaultJavaRT(SaxonProcessor::sxn_environ);
262
    } else {
263
#ifdef DEBUG
264
        std::cerr<<"SaxonProc constructor: jvm exists! jvmCreatedCPP="<<jvmCreatedCPP<<std::endl;
265
#endif
266

    
267
    }
268

    
269

    
270
    versionClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/Version");
271
    procClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/Processor");
272
    saxonCAPIClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/option/cpp/SaxonCAPI");
273

    
274
    jobject proci = createSaxonProcessor(SaxonProcessor::sxn_environ->env, procClass, "(Z)V", nullptr, licensei);
275
    proc = SaxonProcessor::sxn_environ->env->NewGlobalRef(proci);
276
    if (!proc) {
277
        std::cout << "proc is nullptr in SaxonProcessor constructor" << std::endl;
278
    }
279

    
280
    xdmAtomicClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmAtomicValue");
281
#ifdef DEBUG
282
    jmethodID debugMID = SaxonProcessor::sxn_environ->env->GetStaticMethodID(saxonCAPIClass, "setDebugMode", "(Z)V");
283
    SaxonProcessor::sxn_environ->env->CallStaticVoidMethod(saxonCAPIClass, debugMID, (jboolean)true);
284
#endif
285
}
286

    
287
SaxonProcessor::SaxonProcessor(const char *configFile) {
288
    cwd = "";
289
    versionStr = nullptr;
290

    
291
    if (SaxonProcessor::jvmCreatedCPP == 0) {
292
        SaxonProcessor::jvmCreatedCPP = 1;
293
        //SaxonProcessor::sxn_environ= new sxnc_environment;
294
        SaxonProcessor::sxn_environ = (sxnc_environment *) malloc(sizeof(sxnc_environment));
295

    
296
        /*
297
         * First of all, load required component.
298
         * By the time of JET initialization, all components should be loaded.
299
         */
300

    
301
        SaxonProcessor::sxn_environ->myDllHandle = loadDefaultDll();
302

    
303
        /*
304
         * Initialize JET run-time.
305
         * The handle of loaded component is used to retrieve Invocation API.
306
         */
307
        initDefaultJavaRT(SaxonProcessor::sxn_environ);
308
    }
309

    
310
    versionClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/Version");
311

    
312
    procClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/Processor");
313
    saxonCAPIClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/option/cpp/SaxonCAPI");
314

    
315
    static jmethodID mIDcreateProc = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(saxonCAPIClass,
316
                                                                                                     "createSaxonProcessor",
317
                                                                                                     "(Ljava/lang/String;)Lnet/sf/saxon/s9api/Processor;");
318
    if (!mIDcreateProc) {
319
        std::cerr << "Error: SaxonDll." << "getPrimitiveTypeName"
320
                  << " not found\n" << std::endl;
321
        return;
322
    }
323
    jobject proci = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(saxonCAPIClass, mIDcreateProc,
324
                                                                             SaxonProcessor::sxn_environ->env->NewStringUTF(
325
                                                                                     configFile));
326
    proc = SaxonProcessor::sxn_environ->env->NewGlobalRef(proci);
327
    if (!proc) {
328
        checkAndCreateException(saxonCAPIClass);
329
        std::cerr << "Error: " << getDllname() << ". processor is nullptr in constructor(configFile)" << std::endl;
330
        return;
331
    }
332

    
333
    licensei = true;
334
#ifdef DEBUG
335

    
336
    std::cerr<<"SaxonProc constructor(configFile)"<<std::endl;
337
#endif
338
    xdmAtomicClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmAtomicValue");
339
}
340

    
341
SaxonProcessor::~SaxonProcessor() {
342
    clearConfigurationProperties();
343
    if(proc) {
344
            SaxonProcessor::sxn_environ->env->DeleteGlobalRef(proc);
345
    }
346
    if (versionStr != nullptr) {
347
        delete versionStr;
348
        versionStr = nullptr;
349
    }
350
    exceptionClear();
351
}
352

    
353

    
354
bool SaxonProcessor::isSchemaAwareProcessor() {
355
    if (!licensei) {
356
        return false;
357
    } else {
358
        static jmethodID MID_schema = (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(procClass,
359
                                                                                                "isSchemaAware", "()Z");
360
        if (!MID_schema) {
361
            std::cerr << "\nError: Saxonc " << "SaxonProcessor.isSchemaAware()" << " not found" << std::endl;
362
            return false;
363
        }
364

    
365
        licensei = (jboolean) (SaxonProcessor::sxn_environ->env->CallBooleanMethod(proc, MID_schema));
366
        return licensei;
367

    
368
    }
369

    
370
}
371

    
372
void SaxonProcessor::applyConfigurationProperties() {
373
    if (configProperties.size() > 0) {
374
        int size = configProperties.size();
375
        jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/String");
376
        jobjectArray stringArray1 = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size, stringClass, 0);
377
        jobjectArray stringArray2 = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size, stringClass, 0);
378
        static jmethodID mIDappConfig = nullptr;
379
        if (mIDappConfig == nullptr) {
380
            mIDappConfig = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(saxonCAPIClass,
381
                                                                                           "applyToConfiguration",
382
                                                                                           "(Lnet/sf/saxon/s9api/Processor;[Ljava/lang/String;[Ljava/lang/String;)V");
383
            if (!mIDappConfig) {
384
                std::cerr << "Error: SaxonDll." << "applyToConfiguration"
385
                          << " not found\n" << std::endl;
386
                return;
387
            }
388
        }
389
        int i = 0;
390
        std::map<std::string, std::string>::iterator iter = configProperties.begin();
391
        for (iter = configProperties.begin(); iter != configProperties.end(); ++iter, i++) {
392
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(stringArray1, i,
393
                                                                    SaxonProcessor::sxn_environ->env->NewStringUTF(
394
                                                                            (iter->first).c_str()));
395
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(stringArray2, i,
396
                                                                    SaxonProcessor::sxn_environ->env->NewStringUTF(
397
                                                                            (iter->second).c_str()));
398
        }
399
        SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(saxonCAPIClass, mIDappConfig, proc, stringArray1,
400
                                                                 stringArray2);
401
        if (exceptionOccurred()) {
402
            createException();
403
        }
404
        SaxonProcessor::sxn_environ->env->DeleteLocalRef(stringArray1);
405
        SaxonProcessor::sxn_environ->env->DeleteLocalRef(stringArray2);
406

    
407
    }
408
}
409

    
410

    
411
jobjectArray SaxonProcessor::createJArray(XdmValue **values, int length) {
412
    jobjectArray valueArray = nullptr;
413

    
414
    jclass xdmValueClass = lookForClass(SaxonProcessor::sxn_environ->env,
415
                                        "net/sf/saxon/s9api/XdmValue");
416

    
417

    
418
    valueArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) length,
419
                                                                  xdmValueClass, 0);
420

    
421
    for (int i = 0; i < length; i++) {
422
#ifdef DEBUG
423
        std::string s1 = typeid(values[i]).name();
424
        std::cerr<<"In createJArray\nType of itr:"<<s1<<std::endl;
425

    
426

    
427
        jobject xx = values[i]->getUnderlyingValue();
428

    
429
        if(xx == nullptr) {
430
            std::cerr<<"value failed"<<std::endl;
431
        } else {
432

    
433
            std::cerr<<"Type of value:"<<(typeid(xx).name())<<std::endl;
434
        }
435
        if(values[i]->getUnderlyingValue() == nullptr) {
436
            std::cerr<<"value["<<i<<"]->getUnderlyingValue() is nullptr"<<std::endl;
437
        }
438
#endif
439
        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(valueArray, i, values[i]->getUnderlyingValue());
440
    }
441
    return valueArray;
442

    
443
}
444

    
445

    
446
JParameters SaxonProcessor::createParameterJArray(std::map<std::string, XdmValue *> parameters,
447
                                                  std::map<std::string, std::string> properties) {
448
    JParameters comboArrays;
449
    comboArrays.stringArray = nullptr;
450
    comboArrays.objectArray = nullptr;
451
    jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env,
452
                                      "java/lang/Object");
453
    jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env,
454
                                      "java/lang/String");
455

    
456
    int size = parameters.size() + properties.size();
457
#ifdef DEBUG
458
    std::cerr<<"Properties size: "<<properties.size()<<std::endl;
459
    std::cerr<<"Parameter size: "<<parameters.size()<<std::endl;
460
#endif
461
    if (size > 0) {
462

    
463
        comboArrays.objectArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
464
                                                                                   objectClass, 0);
465
        comboArrays.stringArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
466
                                                                                   stringClass, 0);
467
        int i = 0;
468
        for (std::map<std::string, XdmValue *>::iterator iter =
469
                parameters.begin(); iter != parameters.end(); ++iter, i++) {
470

    
471
#ifdef DEBUG
472
            std::cerr<<"map 1"<<std::endl;
473
            std::cerr<<"iter->first"<<(iter->first).c_str()<<std::endl;
474
#endif
475
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(comboArrays.stringArray, i,
476
                                                                    SaxonProcessor::sxn_environ->env->NewStringUTF(
477
                                                                            (iter->first).c_str()));
478
#ifdef DEBUG
479
            std::string s1 = typeid(iter->second).name();
480
            std::cerr<<"Type of itr:"<<s1<<std::endl;
481

    
482
            if((iter->second) == nullptr) {std::cerr<<"iter->second is nullptr"<<std::endl;
483
            } else {
484
                std::cerr<<"getting underlying value"<<std::endl;
485
            jobject xx = (iter->second)->getUnderlyingValue();
486

    
487
            if(xx == nullptr) {
488
                std::cerr<<"value failed"<<std::endl;
489
            } else {
490

    
491
                std::cerr<<"Type of value:"<<(typeid(xx).name())<<std::endl;
492
            }
493
            if((iter->second)->getUnderlyingValue() == nullptr) {
494
                std::cerr<<"(iter->second)->getUnderlyingValue() is nullptr"<<std::endl;
495
            }}
496
#endif
497

    
498
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(comboArrays.objectArray, i,
499
                                                                    (iter->second)->getUnderlyingValue());
500

    
501
        }
502

    
503
        for (std::map<std::string, std::string>::iterator iter =
504
                properties.begin(); iter != properties.end(); ++iter, i++) {
505
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(comboArrays.stringArray, i,
506
                                                                    SaxonProcessor::sxn_environ->env->NewStringUTF(
507
                                                                            (iter->first).c_str()));
508
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(comboArrays.objectArray, i,
509
                                                                    SaxonProcessor::sxn_environ->env->NewStringUTF(
510
                                                                            (iter->second).c_str()));
511
        }
512

    
513
        return comboArrays;
514

    
515
    } else {
516
        return comboArrays;
517
    }
518
}
519

    
520
JParameters SaxonProcessor::createParameterJArray2(std::map<std::string, XdmValue *> parameters) {
521
    JParameters comboArrays;
522
    comboArrays.stringArray = nullptr;
523
    comboArrays.objectArray = nullptr;
524
    jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env,
525
                                      "java/lang/Object");
526
    jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env,
527
                                      "java/lang/String");
528

    
529
    int size = parameters.size();
530
#ifdef DEBUG
531
    std::cerr<<"Parameter size: "<<parameters.size()<<std::endl;
532
#endif
533
    if (size > 0) {
534

    
535
        comboArrays.objectArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
536
                                                                                   objectClass, 0);
537
        comboArrays.stringArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
538
                                                                                   stringClass, 0);
539
        int i = 0;
540
        for (std::map<std::string, XdmValue *>::iterator iter =
541
                parameters.begin(); iter != parameters.end(); ++iter, i++) {
542

    
543
#ifdef DEBUG
544
            std::cerr<<"map 1"<<std::endl;
545
            std::cerr<<"iter->first"<<(iter->first).c_str()<<std::endl;
546
#endif
547
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(comboArrays.stringArray, i,
548
                                                                    SaxonProcessor::sxn_environ->env->NewStringUTF(
549
                                                                            (iter->first).c_str()));
550
#ifdef DEBUG
551
            std::string s1 = typeid(iter->second).name();
552
            std::cerr<<"Type of itr:"<<s1<<std::endl;
553

    
554
            if((iter->second) == nullptr) {std::cerr<<"iter->second is nullptr"<<std::endl;
555
            } else {
556
                std::cerr<<"getting underlying value"<<std::endl;
557
            jobject xx = (iter->second)->getUnderlyingValue();
558

    
559
            if(xx == nullptr) {
560
                std::cerr<<"value failed"<<std::endl;
561
            } else {
562

    
563
                std::cerr<<"Type of value:"<<(typeid(xx).name())<<std::endl;
564
            }
565
            if((iter->second)->getUnderlyingValue() == nullptr) {
566
                std::cerr<<"(iter->second)->getUnderlyingValue() is nullptr"<<std::endl;
567
            }}
568
#endif
569

    
570
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(comboArrays.objectArray, i,
571
                                                                    (iter->second)->getUnderlyingValue());
572

    
573
        }
574

    
575

    
576
        return comboArrays;
577

    
578
    } else {
579
        return comboArrays;
580
    }
581
}
582

    
583

    
584
SaxonProcessor &SaxonProcessor::operator=(const SaxonProcessor &other) {
585
    versionClass = other.versionClass;
586
    procClass = other.procClass;
587
    saxonCAPIClass = other.saxonCAPIClass;
588
    cwd = other.cwd;
589
    proc = SaxonProcessor::sxn_environ->env->NewGlobalRef(other.proc);
590
    parameters = other.parameters;
591
    configProperties = other.configProperties;
592
    licensei = other.licensei;
593
    exception = other.exception;
594
    return *this;
595
}
596

    
597
SaxonProcessor::SaxonProcessor(const SaxonProcessor &other) {
598
    versionClass = other.versionClass;
599
    procClass = other.procClass;
600
    saxonCAPIClass = other.saxonCAPIClass;
601
    cwd = other.cwd;
602
    proc = SaxonProcessor::sxn_environ->env->NewGlobalRef(other.proc);
603
    parameters = other.parameters;
604
    configProperties = other.configProperties;
605
    licensei = other.licensei;
606
    exception = other.exception;
607
}
608

    
609

    
610

    
611
void SaxonProcessor::setResourcesDirectory(const char *dir){}
612

    
613
XsltProcessor *SaxonProcessor::newXsltProcessor() {
614
    return (new XsltProcessor(this, cwd));
615
}
616

    
617
Xslt30Processor *SaxonProcessor::newXslt30Processor() {
618
    return (new Xslt30Processor(this, cwd));
619
}
620

    
621
XQueryProcessor *SaxonProcessor::newXQueryProcessor() {
622
    return (new XQueryProcessor(this, cwd));
623
}
624

    
625
XPathProcessor *SaxonProcessor::newXPathProcessor() {
626
    return (new XPathProcessor(this, cwd));
627
}
628

    
629
SchemaValidator *SaxonProcessor::newSchemaValidator() {
630
    if (licensei) {
631
        return (new SchemaValidator(this, cwd));
632
    } else {
633
        std::cerr << "\nError: Processor is not licensed for schema processing!" << std::endl;
634
        return nullptr;
635
    }
636
}
637

    
638

    
639
const char *SaxonProcessor::version() {
640
    if (versionStr == nullptr) {
641

    
642
        static jmethodID MID_version = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(saxonCAPIClass,
643
                                                                                                       "getProductVersion",
644
                                                                                                       "(Lnet/sf/saxon/s9api/Processor;)Ljava/lang/String;");
645
        if (!MID_version) {
646
            std::cerr << "\nError: MyClassInDll " << "SaxonCAPI.getProductVersion()" << " not found" << std::endl;
647
            return nullptr;
648
        }
649

    
650
        jstring jstr = (jstring) (SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(saxonCAPIClass, MID_version,
651
                                                                                           proc));
652
        const char *tempVersionStr = SaxonProcessor::sxn_environ->env->GetStringUTFChars(jstr, nullptr);
653
        int verLen = strlen(tempVersionStr) + 22 + strlen(CVERSION) + 1;
654
        versionStr = new char[verLen];
655
        snprintf(versionStr, verLen, "Saxon/C %s %s %s", CVERSION, "running with", tempVersionStr);
656
        SaxonProcessor::sxn_environ->env->ReleaseStringUTFChars(jstr, tempVersionStr);
657

    
658

    
659
    }
660

    
661
    return versionStr;
662
}
663

    
664
void SaxonProcessor::setcwd(const char *dir) {
665
    if(dir != nullptr) {
666
        cwd = std::string(dir);
667
    }
668
}
669

    
670
const char *SaxonProcessor::getcwd() {
671
    return cwd.c_str();
672
}
673

    
674

    
675
void SaxonProcessor::setCatalog(const char *catalogFile, bool isTracing) {
676
    jclass xmlResolverClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/trans/XmlCatalogResolver");
677
    static jmethodID catalogMID = SaxonProcessor::sxn_environ->env->GetStaticMethodID(xmlResolverClass, "setCatalog",
678
                                                                                      "(Ljava/lang/String;Lnet/sf/saxon/Configuration;Z)V");
679

    
680
    if (!catalogMID) {
681
        std::cerr << "\nError: Saxonc." << "setCatalog()" << " not found" << std::endl;
682
        return;
683
    }
684
    if (catalogFile == nullptr) {
685

    
686
        return;
687
    }
688
    static jmethodID configMID = SaxonProcessor::sxn_environ->env->GetMethodID(procClass, "getUnderlyingConfiguration",
689
                                                                               "()Lnet/sf/saxon/Configuration;");
690

    
691
    if (!configMID) {
692
        std::cerr << "\nError: Saxonc." << "getUnderlyingConfiguration()" << " not found" << std::endl;
693
        return;
694
    }
695

    
696

    
697
    if (!proc) {
698
        createException("Processor is null in SaxonProcessor.setCatalog");
699
        return;
700
    }
701

    
702
    jobject configObj = SaxonProcessor::sxn_environ->env->CallObjectMethod(proc, configMID);
703

    
704
    if (!configObj) {
705
        std::cout << "proc is null in SaxonProcessor setcatalog - config obj" << std::endl;
706
        return;
707
    }
708
    SaxonProcessor::sxn_environ->env->CallStaticVoidMethod(xmlResolverClass, catalogMID,
709
                                                           SaxonProcessor::sxn_environ->env->NewStringUTF(catalogFile),
710
                                                           configObj, (jboolean) isTracing);
711
#ifdef DEBUG
712
    SaxonProcessor::sxn_environ->env->ExceptionDescribe();
713
#endif
714

    
715
}
716

    
717

    
718
XdmNode *SaxonProcessor::parseXmlFromString(const char *source) {
719

    
720
    jmethodID mID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(saxonCAPIClass, "parseXmlString",
721
                                                                                    "(Ljava/lang/String;Lnet/sf/saxon/s9api/Processor;Lnet/sf/saxon/s9api/SchemaValidator;Ljava/lang/String;)Lnet/sf/saxon/s9api/XdmNode;");
722
    if (!mID) {
723
        std::cerr << "\nError: Saxonc." << "parseXmlString()" << " not found" << std::endl;
724
        return nullptr;
725
    }
726
//TODO SchemaValidator
727

    
728
    if(source == nullptr) {
729
        createException("Source string is NULL");
730
        return nullptr;
731
    }
732

    
733
    jobject xdmNodei = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(saxonCAPIClass, mID,
734
                                                                                SaxonProcessor::sxn_environ->env->NewStringUTF(
735
                                                                                        cwd.c_str()), proc, nullptr,
736
                                                                                SaxonProcessor::sxn_environ->env->NewStringUTF(
737
                                                                                        source));
738
    if (xdmNodei) {
739
        XdmNode *value = nullptr;
740
        value = new XdmNode(xdmNodei);
741
        SaxonProcessor::sxn_environ->env->DeleteLocalRef(xdmNodei);
742
        return value;
743
    } else if (exceptionOccurred()) {
744
        createException();
745
    }
746

    
747
#ifdef DEBUG
748
    SaxonProcessor::sxn_environ->env->ExceptionDescribe();
749
#endif
750

    
751
    return nullptr;
752
}
753

    
754
int SaxonProcessor::getNodeKind(jobject obj) {
755
    jclass xdmNodeClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/s9api/XdmNode;");
756
    static jmethodID nodeKindMID = (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(xdmNodeClass,
757
                                                                                             "getNodeKind",
758
                                                                                             "()Lnet/sf/saxon/s9api/XdmNodeKind;");
759
    if (!nodeKindMID) {
760
        std::cerr << "Error: MyClassInDll." << "getNodeKind" << " not found\n"
761
                  << std::endl;
762
        return 0;
763
    }
764

    
765
    jobject nodeKindObj = (SaxonProcessor::sxn_environ->env->CallObjectMethod(obj, nodeKindMID));
766
    if (!nodeKindObj) {
767

    
768
        return 0;
769
    }
770
    jclass xdmUtilsClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/option/cpp/XdmUtils;");
771

    
772
    jmethodID mID2 = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmUtilsClass,
773
                                                                                     "convertNodeKindType",
774
                                                                                     "(Lnet/sf/saxon/s9api/XdmNodeKind;)I");
775

    
776
    if (!mID2) {
777
        std::cerr << "Error: MyClassInDll." << "convertNodeKindType" << " not found\n"
778
                  << std::endl;
779
        return 0;
780
    }
781
    if (!nodeKindObj) {
782
        return 0;
783
    }
784
    int nodeKind = (int) (SaxonProcessor::sxn_environ->env->CallStaticIntMethod(xdmUtilsClass, mID2, nodeKindObj));
785
    return nodeKind;
786
}
787

    
788

    
789
XdmNode *SaxonProcessor::parseXmlFromFile(const char *source) {
790

    
791
    jmethodID mID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(saxonCAPIClass, "parseXmlFile",
792
                                                                                    "(Lnet/sf/saxon/s9api/Processor;Ljava/lang/String;Lnet/sf/saxon/s9api/SchemaValidator;Ljava/lang/String;)Lnet/sf/saxon/s9api/XdmNode;");
793
    if (!mID) {
794
        std::cerr << "\nError: Saxonc.Dll " << "parseXmlFile()" << " not found" << std::endl;
795
        return nullptr;
796
    }
797
//TODO SchemaValidator
798
    jobject xdmNodei = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(saxonCAPIClass, mID, proc,
799
                                                                                SaxonProcessor::sxn_environ->env->NewStringUTF(
800
                                                                                        cwd.c_str()), nullptr,
801
                                                                                SaxonProcessor::sxn_environ->env->NewStringUTF(
802
                                                                                        source));
803
    if (exceptionOccurred()) {
804
        createException();
805

    
806
    } else {
807

    
808
        XdmNode *value = new XdmNode(xdmNodei);
809
        return value;
810
    }
811
    return nullptr;
812
}
813

    
814
XdmNode *SaxonProcessor::parseXmlFromUri(const char *source) {
815

    
816
    jmethodID mID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(saxonCAPIClass, "parseXmlFile",
817
                                                                                    "(Lnet/sf/saxon/s9api/Processor;Ljava/lang/String;Ljava/lang/String;)Lnet/sf/saxon/s9api/XdmNode;");
818
    if (!mID) {
819
        std::cerr << "\nError: Saxonc.Dll " << "parseXmlFromUri()" << " not found" << std::endl;
820
        return nullptr;
821
    }
822
    jobject xdmNodei = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(saxonCAPIClass, mID, proc,
823
                                                                                SaxonProcessor::sxn_environ->env->NewStringUTF(
824
                                                                                        ""),
825
                                                                                SaxonProcessor::sxn_environ->env->NewStringUTF(
826
                                                                                        source));
827
    if (exceptionOccurred()) {
828
        createException();
829
    } else {
830
        XdmNode *value = new XdmNode(xdmNodei);
831
        return value;
832
    }
833
    return nullptr;
834
}
835

    
836

    
837
/**
838
   * Set a configuration property.
839
   *
840
   * @param name of the property
841
   * @param value of the property
842
   */
843
void SaxonProcessor::setConfigurationProperty(const char *name, const char *value) {
844
    if (name != nullptr) {
845
        configProperties.insert(
846
                std::pair<std::string, std::string>(std::string(name), std::string((value == nullptr ? "" : value))));
847
    }
848
}
849

    
850
void SaxonProcessor::clearConfigurationProperties() {
851
    configProperties.clear();
852
}
853

    
854

    
855
void SaxonProcessor::release() {
856
    if (SaxonProcessor::jvmCreatedCPP != 0) {
857
        SaxonProcessor::jvmCreatedCPP = 0;
858
        //std::cerr<<"SaxonProc: JVM finalized calling !"<<std::endl;
859
        finalizeJavaRT(SaxonProcessor::sxn_environ->jvm);
860

    
861
        delete SaxonProcessor::sxn_environ;
862
        /*clearParameters();
863
        clearProperties();*/
864
    } else {
865
#ifdef DEBUG
866
        std::cerr << "SaxonProc: JVM finalize not called!" << std::endl;
867
#endif
868
    }
869
}
870

    
871

    
872
/* ========= Factory method for Xdm ======== */
873

    
874
XdmAtomicValue *SaxonProcessor::makeStringValue(const char *str) {
875
    jobject obj = getJavaStringValue(SaxonProcessor::sxn_environ, str);
876
    static jmethodID mssID_atomic = nullptr;
877
    if (mssID_atomic == nullptr) {
878
        mssID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>",
879
                                                                                  "(Ljava/lang/String;)V"));
880
    }
881
    if (!mssID_atomic) {
882
        std::cerr << "XdmAtomic constructor (String)" << std::endl;
883
        return nullptr;
884
    }
885
    jobject obj2 = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mssID_atomic, obj));
886
    XdmAtomicValue *value = new XdmAtomicValue(obj2, "xs:string");
887
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
888
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj2);
889
    return value;
890
}
891

    
892
XdmAtomicValue *SaxonProcessor::makeStringValue(std::string str) {
893
    jobject obj = getJavaStringValue(SaxonProcessor::sxn_environ, str.c_str());
894
    static jmethodID msID_atomic = nullptr;
895
    if (msID_atomic == nullptr) {
896
        msID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>",
897
                                                                                 "(Ljava/lang/String;)V"));
898
    }
899
    if (!msID_atomic) {
900
        std::cerr << "XdmAtomic constructor (String)" << std::endl;
901
        return nullptr;
902
    }
903
    jobject obj2 = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, msID_atomic, obj));
904
    XdmAtomicValue *value = new XdmAtomicValue(obj2, "xs:string");
905
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
906
    return value;
907
}
908

    
909
XdmAtomicValue *SaxonProcessor::makeIntegerValue(int i) {
910
    //jobject obj = integerValue(*SaxonProcessor::sxn_environ, i);
911
    static jmethodID miiID_atomic = nullptr;
912
    if (miiID_atomic == nullptr) {
913
        miiID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(J)V"));
914
    }
915
    if (!miiID_atomic) {
916
        std::cerr << "XdmAtomic constructor (J)" << std::endl;
917
        return nullptr;
918
    }
919
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, miiID_atomic, (jlong) i));
920
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}integer");
921
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
922
    return value;
923
}
924

    
925
XdmAtomicValue *SaxonProcessor::makeDoubleValue(double d) {
926
    //jobject obj = doubleValue(*SaxonProcessor::sxn_environ, d);
927
    static jmethodID mdID_atomic = nullptr;
928
    if (mdID_atomic == nullptr) {
929
        mdID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(D)V"));
930
    }
931
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mdID_atomic, (jdouble) d));
932
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}double");
933
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
934
    return value;
935
}
936

    
937
XdmAtomicValue *SaxonProcessor::makeFloatValue(float d) {
938
    //jobject obj = doubleValue(*SaxonProcessor::sxn_environ, d);
939
    static jmethodID mfID_atomic = nullptr;
940
    if (mfID_atomic == nullptr) {
941
        mfID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(F)V"));
942
    }
943
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mfID_atomic, (jfloat) d));
944
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}float");
945
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
946
    return value;
947
}
948

    
949
XdmAtomicValue *SaxonProcessor::makeLongValue(long l) {
950
    //jobject obj = longValue(*SaxonProcessor::sxn_environ, l);
951
    static jmethodID mlID_atomic = nullptr;
952
    if (mlID_atomic == nullptr) {
953
        mlID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(J)V"));
954
    }
955
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mlID_atomic, (jlong) l));
956
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}long");
957
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
958
    return value;
959
}
960

    
961
XdmAtomicValue *SaxonProcessor::makeBooleanValue(bool b) {
962
    //jobject obj = booleanValue(*SaxonProcessor::sxn_environ, b);
963
    static jmethodID mID_atomic = nullptr;
964
    if (mID_atomic == nullptr) {
965
        mID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(Z)V"));
966
    }
967
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mID_atomic, (jboolean) b));
968
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}boolean");
969
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
970
    return value;
971
}
972

    
973
XdmAtomicValue *SaxonProcessor::makeQNameValue(const char *str) {
974
    jobject val = xdmValueAsObj(SaxonProcessor::sxn_environ, "QName", str);
975
    XdmAtomicValue *value = new XdmAtomicValue(val, "QName");
976
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(val);
977
    return value;
978
}
979

    
980
XdmAtomicValue *SaxonProcessor::makeAtomicValue(const char *typei, const char *strValue) {
981
    jobject obj = xdmValueAsObj(SaxonProcessor::sxn_environ, typei, strValue);
982
    XdmAtomicValue *value = new XdmAtomicValue(obj, typei);
983
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
984
    return value;
985
}
986

    
987
const char *SaxonProcessor::getStringValue(XdmItem *item) {
988
    const char *result = stringValue(SaxonProcessor::sxn_environ, item->getUnderlyingValue());
989
#ifdef DEBUG
990
    if(result == nullptr) {
991
        std::cout<<"getStringValue of XdmItem is nullptr"<<std::endl;
992
    } else {
993
        std::cout<<"getStringValue of XdmItem is OK"<<std::endl;
994
    }
995
#endif
996

    
997
    return result;
998

    
999
}
1000

    
1001
#if CVERSION_API_NO >= 123
1002

    
1003
XdmArray *SaxonProcessor::makeArray(short *input, int length) {
1004
    if (input == nullptr) {
1005
        std::cerr << "Error found when converting string to XdmArray" << std::endl;
1006
        return nullptr;
1007
    }
1008
    jclass xdmArrayClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/s9api/XdmArray;");
1009
    static jmethodID mmssID = nullptr;
1010
    if (mmssID == nullptr) {
1011
        mmssID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmArrayClass, "makeArray",
1012
                                                                                 "([S)Lnet/sf/saxon/s9api/XdmArray;");
1013
    }
1014
    if (!mmssID) {
1015
        std::cerr << "\nError: Saxonc.Dll " << "makeArray([S)" << " not found" << std::endl;
1016
        return nullptr;
1017
    }
1018

    
1019

    
1020
    jshortArray sArray = nullptr;
1021

    
1022
    sArray = SaxonProcessor::sxn_environ->env->NewShortArray((jint) length);
1023
    jshort fill[length];
1024
    for (int i = 0; i < length; i++) {
1025
        fill[i] = input[i];
1026
    }
1027
    SaxonProcessor::sxn_environ->env->SetShortArrayRegion(sArray, 0, length, fill);
1028

    
1029
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmssID, sArray);
1030
    if (!xdmArrayi) {
1031
        std::cerr << "Error found when converting string to XdmArray";
1032
        return nullptr;
1033
    }
1034

    
1035
    if (exceptionOccurred()) {
1036
        createException();
1037
    } else {
1038
        XdmArray *value = new XdmArray(xdmArrayi);
1039
        return value;
1040
    }
1041
    return nullptr;
1042
}
1043

    
1044

    
1045
XdmArray *SaxonProcessor::makeArray(int *input, int length) {
1046
    if (input == nullptr) {
1047
        std::cerr << "Error found when converting string to XdmArray";
1048
        return nullptr;
1049
    }
1050
    jclass xdmArrayClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/s9api/XdmArray;");
1051
    static jmethodID mmiiID = nullptr;
1052
    if (mmiiID == nullptr) {
1053
        mmiiID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmArrayClass, "makeArray",
1054
                                                                                 "([I)Lnet/sf/saxon/s9api/XdmArray;");
1055
    }
1056
    if (!mmiiID) {
1057
        std::cerr << "\nError: Saxonc.Dll " << "makeArray([I)" << " not found" << std::endl;
1058
        return nullptr;
1059
    }
1060

    
1061

    
1062
    jintArray iArray = nullptr;
1063

    
1064
    iArray = SaxonProcessor::sxn_environ->env->NewIntArray((jint) length);
1065
    jint fill[length];
1066
    for (int i = 0; i < length; i++) {
1067
        fill[i] = input[i];
1068
    }
1069
    SaxonProcessor::sxn_environ->env->SetIntArrayRegion(iArray, 0, length, fill);
1070

    
1071

    
1072
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmiiID, iArray);
1073
    if (!xdmArrayi) {
1074
        std::cerr << "Error found when converting string to XdmArray";
1075
        return nullptr;
1076
    }
1077
    if (exceptionOccurred()) {
1078
        createException();
1079
    } else {
1080
        XdmArray *value = new XdmArray(xdmArrayi);
1081
        return value;
1082
    }
1083
    return nullptr;
1084

    
1085
}
1086

    
1087
XdmArray *SaxonProcessor::makeArray(long *input, int length) {
1088
    if (input == nullptr) {
1089
        std::cerr << "Error found when converting string to XdmArray";
1090
        return nullptr;
1091
    }
1092
    jclass xdmArrayClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/s9api/XdmArray;");
1093
    static jmethodID mmiID = nullptr;
1094
    if (mmiID == nullptr) {
1095
        mmiID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmArrayClass, "makeArray",
1096
                                                                                "([J)Lnet/sf/saxon/s9api/XdmArray;");
1097
    }
1098
    if (!mmiID) {
1099
        std::cerr << "\nError: Saxonc.Dll " << "makeArray([J)" << " not found" << std::endl;
1100
        return nullptr;
1101
    }
1102

    
1103

    
1104
    jlongArray lArray = nullptr;
1105

    
1106
    lArray = SaxonProcessor::sxn_environ->env->NewLongArray((jint) length);
1107
    jlong fill[length];
1108
    for (int i = 0; i < length; i++) {
1109
        fill[i] = input[i];
1110
    }
1111
    SaxonProcessor::sxn_environ->env->SetLongArrayRegion(lArray, 0, length, fill);
1112

    
1113

    
1114
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmiID, lArray);
1115
    if (!xdmArrayi) {
1116
        std::cerr << "Error found when converting string to XdmArray";
1117
        return nullptr;
1118
    }
1119
    if (exceptionOccurred()) {
1120
        createException();
1121
    } else {
1122
        XdmArray *value = new XdmArray(xdmArrayi);
1123
        return value;
1124
    }
1125
    return nullptr;
1126
}
1127

    
1128

    
1129
XdmArray *SaxonProcessor::makeArray(bool *input, int length) {
1130
    if (input == nullptr) {
1131
        std::cerr << "Error found when converting string to XdmArray";
1132
        return nullptr;
1133
    }
1134
    jclass xdmArrayClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/s9api/XdmArray;");
1135
    static jmethodID mmbID = nullptr;
1136
    if (mmbID == nullptr) {
1137
        mmbID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmArrayClass, "makeArray",
1138
                                                                                "([Z)Lnet/sf/saxon/s9api/XdmArray;");
1139
    }
1140
    if (!mmbID) {
1141
        std::cerr << "\nError: Saxonc.Dll " << "makeArray([Z)" << " not found" << std::endl;
1142
        return nullptr;
1143
    }
1144

    
1145

    
1146
    jbooleanArray bArray = nullptr;
1147

    
1148
    bArray = SaxonProcessor::sxn_environ->env->NewBooleanArray((jint) length);
1149
    jboolean fill[length];
1150
    for (int i = 0; i < length; i++) {
1151
        fill[i] = input[i];
1152
    }
1153
    SaxonProcessor::sxn_environ->env->SetBooleanArrayRegion(bArray, 0, length, fill);
1154

    
1155

    
1156
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmbID, bArray);
1157
    if (!xdmArrayi) {
1158
        std::cerr << "Error found when converting string to XdmArray";
1159
        return nullptr;
1160
    }
1161
    if (exceptionOccurred()) {
1162
        createException();
1163
    } else {
1164
        XdmArray *value = new XdmArray(xdmArrayi);
1165
        return value;
1166
    }
1167
    return nullptr;
1168

    
1169

    
1170
}
1171

    
1172

    
1173
XdmArray *SaxonProcessor::makeArray(const char **input, int length) {
1174
    if (input == nullptr || length <= 0) {
1175
        std::cerr << "Error found when converting string to XdmArray";
1176
        return nullptr;
1177
    }
1178
    jobject obj = nullptr;
1179
    jclass xdmArrayClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/s9api/XdmArray;");
1180
    jmethodID mmID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmArrayClass, "makeArray",
1181
                                                                                     "([Ljava/lang/Object;)Lnet/sf/saxon/s9api/XdmArray;");
1182

    
1183
    jmethodID mID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>",
1184
                                                                                      "(Ljava/lang/String;)V"));
1185
    jobjectArray valueArray = nullptr;
1186
    jobject obj2 = nullptr;
1187
    valueArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) length, xdmAtomicClass, 0);
1188
    for (int i = 0; i < length; i++) {
1189
        if (input[i] == nullptr) {
1190
            std::cerr << "Error found when converting string to XdmArray";
1191
            return nullptr;
1192
        }
1193
        obj = getJavaStringValue(SaxonProcessor::sxn_environ, input[i]);
1194
        obj2 = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mID_atomic, obj));
1195
        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(valueArray, i, obj2);
1196
    }
1197

    
1198
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmID, valueArray);
1199
    if (!xdmArrayi) {
1200
        std::cerr << "Error found when converting string to XdmArray";
1201
        return nullptr;
1202
    }
1203

    
1204
    if (exceptionOccurred()) {
1205
        checkAndCreateException(saxonCAPIClass);
1206
    } else {
1207
        XdmArray *value = new XdmArray(xdmArrayi);
1208
        return value;
1209
    }
1210
    return nullptr;
1211
}
1212

    
1213

    
1214
XdmMap *SaxonProcessor::makeMap(std::map<XdmAtomicValue *, XdmValue *> dataMap) {
1215
    jobjectArray keyArray = nullptr;
1216
    jobjectArray valueArray = nullptr;
1217
    jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env,
1218
                                      "java/lang/Object");
1219

    
1220
    int size = dataMap.size();
1221

    
1222
    if (size > 0) {
1223

    
1224
        keyArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
1225
                                                                    objectClass, 0);
1226
        valueArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
1227
                                                                      objectClass, 0);
1228
        int i = 0;
1229
        for (std::map<XdmAtomicValue *, XdmValue *>::iterator iter =
1230
                dataMap.begin(); iter != dataMap.end(); ++iter, i++) {
1231

    
1232

    
1233
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(keyArray, i,
1234
                                                                    (iter->first)->getUnderlyingValue());
1235

    
1236
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(valueArray, i,
1237
                                                                    (iter->second)->getUnderlyingValue());
1238

    
1239
        }
1240
        jclass xdmUtilsClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/option/cpp/XdmUtils");
1241
        jmethodID xmID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmUtilsClass, "makeXdmMap",
1242
                                                                                         "([Lnet/sf/saxon/s9api/XdmAtomicValue;[Lnet/sf/saxon/s9api/XdmValue;)Lnet/sf/saxon/s9api/XdmMap;");
1243
        if (!xmID) {
1244
            std::cerr << "Error: SaxonDll." << "makeXdmMap"
1245
                      << " not found\n" << std::endl;
1246
            return nullptr;
1247
        }
1248

    
1249

    
1250
        jobject results = (jobject) (SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmUtilsClass, xmID,
1251
                                                                                              keyArray, valueArray));
1252
        if (exceptionOccurred() || !results) {
1253
            checkAndCreateException(saxonCAPIClass);
1254
        } else {
1255
            return new XdmMap(results);
1256
        }
1257
    }
1258

    
1259
    return nullptr;
1260
}
1261

    
1262
#endif
1263

    
1264

    
(13-13/56)