Project

Profile

Help

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

he / src / main / c / Saxon.C.API / SaxonProcessor.cpp @ 01d6fdb6

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
    std::cerr<< "saxonProc exceptionClear cp0"<<std::endl;
109
    if (exception != nullptr) {
110
        std::cerr<< "saxonProc exception= "<< exception <<std::endl;
111
        delete exception;
112
        exception = nullptr;
113
    }
114

    
115
}
116

    
117

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

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

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

    
129
    exceptionClear();
130

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

    
137
}
138

    
139

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

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

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

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

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

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

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

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

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

    
192

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

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

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

    
205

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

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

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

    
237
}
238

    
239

    
240
SaxonProcessor::SaxonProcessor(bool l) {
241

    
242
    cwd = "";
243
    licensei = l;
244
    versionStr = nullptr;
245
    exception = nullptr;
246

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

    
251

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

    
257
        SaxonProcessor::sxn_environ->myDllHandle = loadDefaultDll();
258

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

    
269
    }
270

    
271

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

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

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

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

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

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

    
303
        SaxonProcessor::sxn_environ->myDllHandle = loadDefaultDll();
304

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

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

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

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

    
335
    licensei = true;
336
#ifdef DEBUG
337

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

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

    
355

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

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

    
370
    }
371

    
372
}
373

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

    
409
    }
410
}
411

    
412

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

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

    
419

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

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

    
428

    
429
        jobject xx = values[i]->getUnderlyingValue();
430

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

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

    
445
}
446

    
447

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

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

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

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

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

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

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

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

    
503
        }
504

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

    
515
        return comboArrays;
516

    
517
    } else {
518
        return comboArrays;
519
    }
520
}
521

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

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

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

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

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

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

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

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

    
575
        }
576

    
577

    
578
        return comboArrays;
579

    
580
    } else {
581
        return comboArrays;
582
    }
583
}
584

    
585

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

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

    
611

    
612

    
613
void SaxonProcessor::setResourcesDirectory(const char *dir){}
614

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

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

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

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

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

    
640

    
641
const char *SaxonProcessor::version() {
642
    if (versionStr == nullptr) {
643

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

    
652
        if(proc == nullptr) {
653
            createException("The Java SaxonProcessor object (i.e. cppXQ) is NULL - Possible exception thrown");
654
            return nullptr;
655
        }
656

    
657
        jstring jstr = (jstring) (SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(saxonCAPIClass, MID_version,
658
                                                                                           proc));
659
        const char *tempVersionStr = SaxonProcessor::sxn_environ->env->GetStringUTFChars(jstr, nullptr);
660
        int verLen = strlen(tempVersionStr) + 22 + strlen(CVERSION) + 1;
661
        versionStr = new char[verLen];
662
        snprintf(versionStr, verLen, "Saxon/C %s %s %s", CVERSION, "running with", tempVersionStr);
663
        SaxonProcessor::sxn_environ->env->ReleaseStringUTFChars(jstr, tempVersionStr);
664

    
665

    
666
    }
667

    
668
    return versionStr;
669
}
670

    
671
void SaxonProcessor::setcwd(const char *dir) {
672
    if(dir != nullptr) {
673
        cwd = std::string(dir);
674
    }
675
}
676

    
677
const char *SaxonProcessor::getcwd() {
678
    return cwd.c_str();
679
}
680

    
681

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

    
687
    if (!catalogMID) {
688
        std::cerr << "\nError: Saxonc." << "setCatalog()" << " not found" << std::endl;
689
        return;
690
    }
691
    if (catalogFile == nullptr) {
692

    
693
        return;
694
    }
695
    static jmethodID configMID = SaxonProcessor::sxn_environ->env->GetMethodID(procClass, "getUnderlyingConfiguration",
696
                                                                               "()Lnet/sf/saxon/Configuration;");
697

    
698
    if (!configMID) {
699
        std::cerr << "\nError: Saxonc." << "getUnderlyingConfiguration()" << " not found" << std::endl;
700
        return;
701
    }
702

    
703

    
704
    if (!proc) {
705
        createException("Processor is null in SaxonProcessor.setCatalog");
706
        return;
707
    }
708

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

    
711
    if (!configObj) {
712
        std::cout << "proc is null in SaxonProcessor setcatalog - config obj" << std::endl;
713
        return;
714
    }
715
    SaxonProcessor::sxn_environ->env->CallStaticVoidMethod(xmlResolverClass, catalogMID,
716
                                                           SaxonProcessor::sxn_environ->env->NewStringUTF(catalogFile),
717
                                                           configObj, (jboolean) isTracing);
718
#ifdef DEBUG
719
    SaxonProcessor::sxn_environ->env->ExceptionDescribe();
720
#endif
721

    
722
}
723

    
724

    
725
XdmNode *SaxonProcessor::parseXmlFromString(const char *source) {
726

    
727
    jmethodID mID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(saxonCAPIClass, "parseXmlString",
728
                                                                                    "(Ljava/lang/String;Lnet/sf/saxon/s9api/Processor;Lnet/sf/saxon/s9api/SchemaValidator;Ljava/lang/String;)Lnet/sf/saxon/s9api/XdmNode;");
729
    if (!mID) {
730
        std::cerr << "\nError: Saxonc." << "parseXmlString()" << " not found" << std::endl;
731
        return nullptr;
732
    }
733
//TODO SchemaValidator
734

    
735
    if(source == nullptr) {
736
        createException("Source string is NULL");
737
        return nullptr;
738
    }
739

    
740
    jobject xdmNodei = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(saxonCAPIClass, mID,
741
                                                                                SaxonProcessor::sxn_environ->env->NewStringUTF(
742
                                                                                        cwd.c_str()), proc, nullptr,
743
                                                                                SaxonProcessor::sxn_environ->env->NewStringUTF(
744
                                                                                        source));
745
    if (xdmNodei) {
746
        XdmNode *value = nullptr;
747
        value = new XdmNode(xdmNodei);
748
        SaxonProcessor::sxn_environ->env->DeleteLocalRef(xdmNodei);
749
        return value;
750
    } else if (exceptionOccurred()) {
751
        createException();
752
    }
753

    
754
#ifdef DEBUG
755
    SaxonProcessor::sxn_environ->env->ExceptionDescribe();
756
#endif
757

    
758
    return nullptr;
759
}
760

    
761
int SaxonProcessor::getNodeKind(jobject obj) {
762
    jclass xdmNodeClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/s9api/XdmNode;");
763
    static jmethodID nodeKindMID = (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(xdmNodeClass,
764
                                                                                             "getNodeKind",
765
                                                                                             "()Lnet/sf/saxon/s9api/XdmNodeKind;");
766
    if (!nodeKindMID) {
767
        std::cerr << "Error: MyClassInDll." << "getNodeKind" << " not found\n"
768
                  << std::endl;
769
        return 0;
770
    }
771

    
772
    jobject nodeKindObj = (SaxonProcessor::sxn_environ->env->CallObjectMethod(obj, nodeKindMID));
773
    if (!nodeKindObj) {
774

    
775
        return 0;
776
    }
777
    jclass xdmUtilsClass = lookForClass(SaxonProcessor::sxn_environ->env, "Lnet/sf/saxon/option/cpp/XdmUtils;");
778

    
779
    jmethodID mID2 = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmUtilsClass,
780
                                                                                     "convertNodeKindType",
781
                                                                                     "(Lnet/sf/saxon/s9api/XdmNodeKind;)I");
782

    
783
    if (!mID2) {
784
        std::cerr << "Error: MyClassInDll." << "convertNodeKindType" << " not found\n"
785
                  << std::endl;
786
        return 0;
787
    }
788
    if (!nodeKindObj) {
789
        return 0;
790
    }
791
    int nodeKind = (int) (SaxonProcessor::sxn_environ->env->CallStaticIntMethod(xdmUtilsClass, mID2, nodeKindObj));
792
    return nodeKind;
793
}
794

    
795

    
796
XdmNode *SaxonProcessor::parseXmlFromFile(const char *source) {
797

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

    
813
    } else {
814

    
815
        XdmNode *value = new XdmNode(xdmNodei);
816
        return value;
817
    }
818
    return nullptr;
819
}
820

    
821
XdmNode *SaxonProcessor::parseXmlFromUri(const char *source) {
822

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

    
843

    
844
/**
845
   * Set a configuration property.
846
   *
847
   * @param name of the property
848
   * @param value of the property
849
   */
850
void SaxonProcessor::setConfigurationProperty(const char *name, const char *value) {
851
    if (name != nullptr) {
852
        configProperties.insert(
853
                std::pair<std::string, std::string>(std::string(name), std::string((value == nullptr ? "" : value))));
854
    }
855
}
856

    
857
void SaxonProcessor::clearConfigurationProperties() {
858
    configProperties.clear();
859
}
860

    
861

    
862
void SaxonProcessor::release() {
863
    if (SaxonProcessor::jvmCreatedCPP != 0) {
864
        SaxonProcessor::jvmCreatedCPP = 0;
865
        //std::cerr<<"SaxonProc: JVM finalized calling !"<<std::endl;
866
        finalizeJavaRT(SaxonProcessor::sxn_environ->jvm);
867

    
868
        delete SaxonProcessor::sxn_environ;
869
        /*clearParameters();
870
        clearProperties();*/
871
    } else {
872
#ifdef DEBUG
873
        std::cerr << "SaxonProc: JVM finalize not called!" << std::endl;
874
#endif
875
    }
876
}
877

    
878

    
879
/* ========= Factory method for Xdm ======== */
880

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

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

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

    
932
XdmAtomicValue *SaxonProcessor::makeDoubleValue(double d) {
933
    //jobject obj = doubleValue(*SaxonProcessor::sxn_environ, d);
934
    static jmethodID mdID_atomic = nullptr;
935
    if (mdID_atomic == nullptr) {
936
        mdID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(D)V"));
937
    }
938
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mdID_atomic, (jdouble) d));
939
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}double");
940
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
941
    return value;
942
}
943

    
944
XdmAtomicValue *SaxonProcessor::makeFloatValue(float d) {
945
    //jobject obj = doubleValue(*SaxonProcessor::sxn_environ, d);
946
    static jmethodID mfID_atomic = nullptr;
947
    if (mfID_atomic == nullptr) {
948
        mfID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(F)V"));
949
    }
950
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mfID_atomic, (jfloat) d));
951
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}float");
952
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
953
    return value;
954
}
955

    
956
XdmAtomicValue *SaxonProcessor::makeLongValue(long l) {
957
    //jobject obj = longValue(*SaxonProcessor::sxn_environ, l);
958
    static jmethodID mlID_atomic = nullptr;
959
    if (mlID_atomic == nullptr) {
960
        mlID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(J)V"));
961
    }
962
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mlID_atomic, (jlong) l));
963
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}long");
964
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
965
    return value;
966
}
967

    
968
XdmAtomicValue *SaxonProcessor::makeBooleanValue(bool b) {
969
    //jobject obj = booleanValue(*SaxonProcessor::sxn_environ, b);
970
    static jmethodID mID_atomic = nullptr;
971
    if (mID_atomic == nullptr) {
972
        mID_atomic = (jmethodID) (SaxonProcessor::sxn_environ->env->GetMethodID(xdmAtomicClass, "<init>", "(Z)V"));
973
    }
974
    jobject obj = (jobject) (SaxonProcessor::sxn_environ->env->NewObject(xdmAtomicClass, mID_atomic, (jboolean) b));
975
    XdmAtomicValue *value = new XdmAtomicValue(obj, "Q{http://www.w3.org/2001/XMLSchema}boolean");
976
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
977
    return value;
978
}
979

    
980
XdmAtomicValue *SaxonProcessor::makeQNameValue(const char *str) {
981
    jobject val = xdmValueAsObj(SaxonProcessor::sxn_environ, "QName", str);
982
    XdmAtomicValue *value = new XdmAtomicValue(val, "QName");
983
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(val);
984
    return value;
985
}
986

    
987
XdmAtomicValue *SaxonProcessor::makeAtomicValue(const char *typei, const char *strValue) {
988
    jobject obj = xdmValueAsObj(SaxonProcessor::sxn_environ, typei, strValue);
989
    XdmAtomicValue *value = new XdmAtomicValue(obj, typei);
990
    SaxonProcessor::sxn_environ->env->DeleteLocalRef(obj);
991
    return value;
992
}
993

    
994
const char *SaxonProcessor::getStringValue(XdmItem *item) {
995
    const char *result = stringValue(SaxonProcessor::sxn_environ, item->getUnderlyingValue());
996
#ifdef DEBUG
997
    if(result == nullptr) {
998
        std::cout<<"getStringValue of XdmItem is nullptr"<<std::endl;
999
    } else {
1000
        std::cout<<"getStringValue of XdmItem is OK"<<std::endl;
1001
    }
1002
#endif
1003

    
1004
    return result;
1005

    
1006
}
1007

    
1008
#if CVERSION_API_NO >= 123
1009

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

    
1026

    
1027
    jshortArray sArray = nullptr;
1028

    
1029
    sArray = SaxonProcessor::sxn_environ->env->NewShortArray((jint) length);
1030
    jshort fill[length];
1031
    for (int i = 0; i < length; i++) {
1032
        fill[i] = input[i];
1033
    }
1034
    SaxonProcessor::sxn_environ->env->SetShortArrayRegion(sArray, 0, length, fill);
1035

    
1036
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmssID, sArray);
1037
    if (!xdmArrayi) {
1038
        std::cerr << "Error found when converting string to XdmArray";
1039
        return nullptr;
1040
    }
1041

    
1042
    if (exceptionOccurred()) {
1043
        createException();
1044
    } else {
1045
        XdmArray *value = new XdmArray(xdmArrayi);
1046
        return value;
1047
    }
1048
    return nullptr;
1049
}
1050

    
1051

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

    
1068

    
1069
    jintArray iArray = nullptr;
1070

    
1071
    iArray = SaxonProcessor::sxn_environ->env->NewIntArray((jint) length);
1072
    jint fill[length];
1073
    for (int i = 0; i < length; i++) {
1074
        fill[i] = input[i];
1075
    }
1076
    SaxonProcessor::sxn_environ->env->SetIntArrayRegion(iArray, 0, length, fill);
1077

    
1078

    
1079
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmiiID, iArray);
1080
    if (!xdmArrayi) {
1081
        std::cerr << "Error found when converting string to XdmArray";
1082
        return nullptr;
1083
    }
1084
    if (exceptionOccurred()) {
1085
        createException();
1086
    } else {
1087
        XdmArray *value = new XdmArray(xdmArrayi);
1088
        return value;
1089
    }
1090
    return nullptr;
1091

    
1092
}
1093

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

    
1110

    
1111
    jlongArray lArray = nullptr;
1112

    
1113
    lArray = SaxonProcessor::sxn_environ->env->NewLongArray((jint) length);
1114
    jlong fill[length];
1115
    for (int i = 0; i < length; i++) {
1116
        fill[i] = input[i];
1117
    }
1118
    SaxonProcessor::sxn_environ->env->SetLongArrayRegion(lArray, 0, length, fill);
1119

    
1120

    
1121
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmiID, lArray);
1122
    if (!xdmArrayi) {
1123
        std::cerr << "Error found when converting string to XdmArray";
1124
        return nullptr;
1125
    }
1126
    if (exceptionOccurred()) {
1127
        createException();
1128
    } else {
1129
        XdmArray *value = new XdmArray(xdmArrayi);
1130
        return value;
1131
    }
1132
    return nullptr;
1133
}
1134

    
1135

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

    
1152

    
1153
    jbooleanArray bArray = nullptr;
1154

    
1155
    bArray = SaxonProcessor::sxn_environ->env->NewBooleanArray((jint) length);
1156
    jboolean fill[length];
1157
    for (int i = 0; i < length; i++) {
1158
        fill[i] = input[i];
1159
    }
1160
    SaxonProcessor::sxn_environ->env->SetBooleanArrayRegion(bArray, 0, length, fill);
1161

    
1162

    
1163
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmbID, bArray);
1164
    if (!xdmArrayi) {
1165
        std::cerr << "Error found when converting string to XdmArray";
1166
        return nullptr;
1167
    }
1168
    if (exceptionOccurred()) {
1169
        createException();
1170
    } else {
1171
        XdmArray *value = new XdmArray(xdmArrayi);
1172
        return value;
1173
    }
1174
    return nullptr;
1175

    
1176

    
1177
}
1178

    
1179

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

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

    
1205
    jobject xdmArrayi = SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmArrayClass, mmID, valueArray);
1206
    if (!xdmArrayi) {
1207
        std::cerr << "Error found when converting string to XdmArray";
1208
        return nullptr;
1209
    }
1210

    
1211
    if (exceptionOccurred()) {
1212
        checkAndCreateException(saxonCAPIClass);
1213
    } else {
1214
        XdmArray *value = new XdmArray(xdmArrayi);
1215
        return value;
1216
    }
1217
    return nullptr;
1218
}
1219

    
1220

    
1221
XdmMap *SaxonProcessor::makeMap(std::map<XdmAtomicValue *, XdmValue *> dataMap) {
1222
    jobjectArray keyArray = nullptr;
1223
    jobjectArray valueArray = nullptr;
1224
    jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env,
1225
                                      "java/lang/Object");
1226

    
1227
    int size = dataMap.size();
1228

    
1229
    if (size > 0) {
1230

    
1231
        keyArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
1232
                                                                    objectClass, 0);
1233
        valueArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
1234
                                                                      objectClass, 0);
1235
        int i = 0;
1236
        for (std::map<XdmAtomicValue *, XdmValue *>::iterator iter =
1237
                dataMap.begin(); iter != dataMap.end(); ++iter, i++) {
1238

    
1239

    
1240
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(keyArray, i,
1241
                                                                    (iter->first)->getUnderlyingValue());
1242

    
1243
            SaxonProcessor::sxn_environ->env->SetObjectArrayElement(valueArray, i,
1244
                                                                    (iter->second)->getUnderlyingValue());
1245

    
1246
        }
1247
        jclass xdmUtilsClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/option/cpp/XdmUtils");
1248
        jmethodID xmID = (jmethodID) SaxonProcessor::sxn_environ->env->GetStaticMethodID(xdmUtilsClass, "makeXdmMap",
1249
                                                                                         "([Lnet/sf/saxon/s9api/XdmAtomicValue;[Lnet/sf/saxon/s9api/XdmValue;)Lnet/sf/saxon/s9api/XdmMap;");
1250
        if (!xmID) {
1251
            std::cerr << "Error: SaxonDll." << "makeXdmMap"
1252
                      << " not found\n" << std::endl;
1253
            return nullptr;
1254
        }
1255

    
1256

    
1257
        jobject results = (jobject) (SaxonProcessor::sxn_environ->env->CallStaticObjectMethod(xdmUtilsClass, xmID,
1258
                                                                                              keyArray, valueArray));
1259
        if (exceptionOccurred() || !results) {
1260
            checkAndCreateException(saxonCAPIClass);
1261
        } else {
1262
            return new XdmMap(results);
1263
        }
1264
    }
1265

    
1266
    return nullptr;
1267
}
1268

    
1269
#endif
1270

    
1271

    
(13-13/56)