Project

Profile

Help

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

he / src / main / c / Saxon.C.API / XQueryProcessor.cpp @ 4ee4355d

1
#include "XQueryProcessor.h"
2
#include "XdmValue.h"
3
#include "XdmItem.h"
4
#include "XdmNode.h"
5
#include "XdmAtomicValue.h"
6

    
7
    XQueryProcessor::XQueryProcessor() {
8
        SaxonProcessor *p = new SaxonProcessor(false);
9
        XQueryProcessor(p, "");
10
     }
11

    
12
    XQueryProcessor::XQueryProcessor(SaxonProcessor *p, std::string curr) {
13
    proc = p;
14

    
15
  
16
     cppClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/option/cpp/XQueryEngine");
17

    
18

    
19
    cppXQ = createSaxonProcessor2 (SaxonProcessor::sxn_environ->env, cppClass, "(Lnet/sf/saxon/s9api/Processor;)V", proc->proc);
20
    
21
#ifdef DEBUG
22
        jmethodID debugMID = SaxonProcessor::sxn_environ->env->GetStaticMethodID(cppClass, "setDebugMode", "(Z)V");
23
        SaxonProcessor::sxn_environ->env->CallStaticVoidMethod(cppClass, debugMID, (jboolean)true);
24
#endif
25

    
26
    exception = nullptr;
27
   // outputfile1 = "";
28
        if(!(proc->cwd.empty()) && curr.empty()){
29
                cwdXQ = proc->cwd;
30
        } else {
31
                cwdXQ = curr;
32
        }
33
}
34

    
35

    
36

    
37
XQueryProcessor::XQueryProcessor(const XQueryProcessor &other) {
38
    cwdXQ = other.cwdXQ;
39
        proc = other.proc; //TODO check thread safety
40
        jclass  cppClass;
41
        jobject cppXQ;
42
        std::map<std::string,XdmValue*> parameters; /*!< map of parameters used for the transformation as (string, value) pairs */
43
        std::map<std::string,std::string> properties;
44

    
45

    
46
}
47

    
48

    
49
XQueryProcessor * XQueryProcessor::clone() {
50
      XQueryProcessor * proc = new XQueryProcessor(*this);
51
      return proc;
52

    
53

    
54
}
55

    
56

    
57
std::map<std::string,XdmValue*>& XQueryProcessor::getParameters(){
58
        std::map<std::string,XdmValue*>& ptr = parameters;
59
        return ptr;
60
}
61

    
62
std::map<std::string,std::string>& XQueryProcessor::getProperties(){
63
        std::map<std::string,std::string> &ptr = properties;
64
        return ptr;
65
}
66

    
67

    
68
    /**
69
     * Set the source document for the query
70
    */
71
    void XQueryProcessor::setContextItem(XdmItem * value){
72
            if(value != nullptr){
73
         value->incrementRefCount();
74
              parameters["node"] = (XdmValue *)value;
75
            }
76
    }
77

    
78

    
79
     void XQueryProcessor::declareNamespace(const char *prefix, const char * uri){
80
        if (prefix == nullptr || uri == nullptr) {
81
                    return;
82
        }  else {
83
            //setProperty("ns-prefix", uri);
84
             int s = properties.size();
85
             std::string skey = std::string("ns-prefix:") + prefix;
86
             properties.insert(std::pair<std::string, std::string>(skey, std::string(uri)));
87

    
88
             if(s == properties.size()) {
89
                 std::map<std::string, std::string>::iterator it;
90
                 it = properties.find(skey);
91
                 if (it != properties.end()) {
92
                       properties.erase(skey);
93
                       properties[skey] = std::string(uri);
94
                 }
95
             }
96

    
97
        }
98
}
99

    
100

    
101
    /**
102
     * Set the source document for the query
103
    */
104
    void XQueryProcessor::setContextItemFromFile(const char * ifile){
105
        setProperty("s", ifile);
106
    }
107

    
108
    /**
109
     * Set the output file where the result is sent
110
    */
111
    void XQueryProcessor::setOutputFile(const char* ofile){
112
      // outputfile1 = std::string(ofile); 
113
       setProperty("o", ofile);
114
    }
115

    
116
    /**
117
     * Set a parameter value used in the query
118
     *
119
     * @param name  of the parameter, as a string
120
     * @param value of the query parameter, or nullptr to clear a previously set value
121
     */
122
    void XQueryProcessor::setParameter(const char * name, XdmValue*value){
123
        if(value != nullptr){
124
                value->incrementRefCount();
125
                int s = parameters.size();
126
                std::string skey = "param:"+std::string(name);
127
                parameters[skey] = value;
128
                if(s == parameters.size()) {
129
            std::map<std::string, XdmValue*>::iterator it;
130
            it = parameters.find(skey);
131
            if (it != parameters.end()) {
132
                XdmValue * valuei = it->second;
133
                if(valuei != nullptr) {
134
                    valuei->decrementRefCount();
135
                    if (valuei->getRefCount() < 1) {
136
                        delete value;
137
                    }
138
                    parameters.erase(skey);
139
                    parameters[skey] = value;
140
                }
141
            }
142
                }
143
        } 
144
    }
145

    
146

    
147
    /**
148
     * Remove a parameter (name, value) pair
149
     *
150
     * @param namespacei currently not used
151
     * @param name  of the parameter
152
     * @return bool - outcome of the romoval
153
     */
154
    bool XQueryProcessor::removeParameter(const char * name){
155
        return (bool)(parameters.erase("param:"+std::string(name)));
156
    }
157
    /**
158
     * Set a property.
159
     *
160
     * @param name of the property
161
     * @param value of the property
162
     */
163
    void XQueryProcessor::setProperty(const char * name, const char * value){
164
#ifdef DEBUG        
165
        if(value == nullptr) {
166
                std::cerr<<"XQueryProc setProperty is nullptr"<<std::endl;
167
        }
168
#endif
169
            if(name != nullptr) {
170
                int s = properties.size();
171
                    std::string skey = std::string(name);
172
                    properties.insert(std::pair<std::string, std::string>(skey, std::string((value == nullptr ? "" : value))));
173

    
174
                    if(s == properties.size()) {
175
                std::map<std::string, std::string>::iterator it;
176
                it = properties.find(skey);
177
                if (it != properties.end()) {
178
                    properties.erase(skey);
179
                    properties[skey] = std::string((value == nullptr ? "" : value));
180
                }
181
                    }
182
            }
183

    
184

    
185

    
186
    }
187

    
188
    void XQueryProcessor::clearParameters(bool delVal){
189
        if(delVal){
190
                       for(std::map<std::string, XdmValue*>::iterator itr = parameters.begin(); itr != parameters.end(); itr++) {
191
                XdmValue *value = itr->second;
192
                if (value != nullptr) {
193
                    value->decrementRefCount();
194
#ifdef DEBUG
195
                    std::cerr<<"XQueryProc.clearParameter() - XdmValue refCount="<<value->getRefCount()<<std::endl;
196
#endif
197
                    if (value->getRefCount() < 1) {
198
                        delete value;
199
                    }
200
                }
201
            }
202
                
203
        } else {
204

    
205
                for(std::map<std::string, XdmValue*>::iterator itr = parameters.begin(); itr != parameters.end(); itr++){
206
                        XdmValue * value = itr->second;
207
                        if(value != nullptr) {
208
                value->decrementRefCount();
209
            }
210
                }
211
        }
212

    
213
        parameters.clear();
214
    }
215

    
216
   void XQueryProcessor::clearProperties(){
217
        properties.clear();
218
        //outputfile1.clear();
219
   }
220

    
221

    
222
   void XQueryProcessor::setcwd(const char* dir){
223
    cwdXQ = std::string(dir);
224
   }
225

    
226
    void XQueryProcessor::setQueryBaseURI(const char * baseURI){
227
        setProperty("base", baseURI);
228
    }
229

    
230

    
231
    void XQueryProcessor::setUpdating(bool updating){
232
     
233
            jmethodID mID =
234
                    (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(cppClass, "setUpdating",
235
                                    "(Z)V");
236
            if (!mID) {
237
            std::cerr << "Error: Saxonc library." << "setUpdating" << " not found\n"
238
                            << std::endl;
239

    
240
            } else {
241

    
242
                            SaxonProcessor::sxn_environ->env->CallObjectMethod(cppXQ, mID,
243
                                            (jboolean)updating);
244
            }
245

    
246
    }
247

    
248
    void XQueryProcessor::executeQueryToFile(const char * infilename, const char * ofilename, const char * query){
249

    
250

    
251
        jmethodID mID = (jmethodID)SaxonProcessor::sxn_environ->env->GetMethodID (cppClass,"executeQueryToFile", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;)V");
252
         if (!mID) {
253
        std::cerr<<"Error: MyClassInDll."<<"executeQueryToFile"<<" not found\n"<<std::endl;
254
    } else {
255
        jobjectArray stringArray = nullptr;
256
        jobjectArray objectArray = nullptr;
257

    
258
        int size = parameters.size() + properties.size();
259
        if(query!= nullptr) size++;
260
        if(infilename!= nullptr) size++;
261
        if(size >0) {
262

    
263
           int i=0;
264
           jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/Object");
265
           jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/String");
266
           objectArray = SaxonProcessor::sxn_environ->env->NewObjectArray( (jint)size, objectClass, 0 );
267
           stringArray = SaxonProcessor::sxn_environ->env->NewObjectArray( (jint)size, stringClass, 0 );
268
           if(query!= nullptr) {
269
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF("qs") );
270
                  SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF(query));
271
             i++;        
272
           }
273
           if(infilename!= nullptr) {
274
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF("s") );
275
                  SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF(infilename));
276
             i++;        
277
           }
278
           for(std::map<std::string, XdmValue* >::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter, i++) {
279
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF( (iter->first).c_str() ) );
280
                bool checkCast = SaxonProcessor::sxn_environ->env->IsInstanceOf((iter->second)->getUnderlyingValue(), lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/option/cpp/XdmValueForCpp") );
281

    
282
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, (jobject)((iter->second)->getUnderlyingValue()) );
283
           }
284
             for(std::map<std::string, std::string >::iterator iter=properties.begin(); iter!=properties.end(); ++iter, i++) {
285
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF( (iter->first).c_str()  ));
286
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, (jobject)(SaxonProcessor::sxn_environ->env->NewStringUTF((iter->second).c_str())) );
287
           }
288
        }
289

    
290
         SaxonProcessor::sxn_environ->env->CallObjectMethod(cppXQ, mID, SaxonProcessor::sxn_environ->env->NewStringUTF(cwdXQ.c_str()), SaxonProcessor::sxn_environ->env->NewStringUTF(ofilename), stringArray, objectArray );
291
          SaxonProcessor::sxn_environ->env->DeleteLocalRef(objectArray);
292
          SaxonProcessor::sxn_environ->env->DeleteLocalRef(stringArray);
293

    
294
        exception = proc->checkAndCreateException(cppClass);
295
         
296
  }
297

    
298

    
299
   }
300

    
301

    
302
    XdmValue * XQueryProcessor::executeQueryToValue(const char * infilename, const char * query){
303

    
304
 jmethodID mID = (jmethodID)SaxonProcessor::sxn_environ->env->GetMethodID (cppClass,"executeQueryToValue", "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;)Lnet/sf/saxon/s9api/XdmValue;");
305
 if (!mID) {
306
        std::cerr<<"Error: MyClassInDll."<<"executeQueryToValue"<<" not found\n"<<std::endl;
307
    } else {
308
        jobjectArray stringArray = nullptr;
309
        jobjectArray objectArray = nullptr;
310

    
311
        int size = parameters.size() + properties.size();
312
        if(query!= nullptr) size++;
313
        if(infilename!= nullptr) size++;
314
        if(size >0) {
315
           int i=0;
316
           jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/Object");
317
           jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/String");
318
           objectArray = SaxonProcessor::sxn_environ->env->NewObjectArray( (jint)size, objectClass, 0 );
319
           stringArray = SaxonProcessor::sxn_environ->env->NewObjectArray( (jint)size, stringClass, 0 );
320

    
321
           if(query!= nullptr) {
322
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF("qs") );
323
                  SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF(query));
324
             i++;        
325
           }
326
           if(infilename!= nullptr) {
327
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF("s") );
328
                  SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF(infilename));
329
             i++;        
330
           }
331
           for(std::map<std::string, XdmValue* >::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter, i++) {
332
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF( (iter->first).c_str() ) );
333
                bool checkCast = SaxonProcessor::sxn_environ->env->IsInstanceOf((iter->second)->getUnderlyingValue(), lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/option/cpp/XdmValueForCpp") );
334

    
335
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, (jobject)((iter->second)->getUnderlyingValue()) );
336
           }
337
             for(std::map<std::string, std::string >::iterator iter=properties.begin(); iter!=properties.end(); ++iter, i++) {
338
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF( (iter->first).c_str()  ));
339
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, (jobject)(SaxonProcessor::sxn_environ->env->NewStringUTF((iter->second).c_str())) );
340
           }
341
        }
342

    
343
          jobject result = (jobject)(SaxonProcessor::sxn_environ->env->CallObjectMethod(cppXQ, mID, SaxonProcessor::sxn_environ->env->NewStringUTF(cwdXQ.c_str()), stringArray, objectArray ));
344
          SaxonProcessor::sxn_environ->env->DeleteLocalRef(objectArray);
345
          SaxonProcessor::sxn_environ->env->DeleteLocalRef(stringArray);
346
    if(result) {
347
                jclass atomicValueClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmAtomicValue");
348
                jclass nodeClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmNode");
349
                jclass functionItemClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmFunctionItem");
350
                XdmValue * value = nullptr;
351
                XdmItem * xdmItem = nullptr;
352

    
353
                if(SaxonProcessor::sxn_environ->env->IsInstanceOf(result, atomicValueClass)           == JNI_TRUE) {
354
                                xdmItem = new XdmAtomicValue(result);
355
                                SaxonProcessor::sxn_environ->env->DeleteLocalRef(result);
356
                                return xdmItem;
357

    
358
                        } else if(SaxonProcessor::sxn_environ->env->IsInstanceOf(result, nodeClass)           == JNI_TRUE) {
359
                                xdmItem = new XdmNode(result);
360
                                SaxonProcessor::sxn_environ->env->DeleteLocalRef(result);
361
                                return xdmItem;
362
                        
363
                        } else if (SaxonProcessor::sxn_environ->env->IsInstanceOf(result, functionItemClass)           == JNI_TRUE) {
364
                /*xdmItem =  new XdmFunctionItem(result);
365
                xdmItem->setProcessor(proc);
366
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(result);*/
367
                return nullptr;// xdmItem;
368
                        } else {
369
                                value = new XdmValue(result, true);
370
                                return value;
371
                        }
372
                        value = new XdmValue();
373
                        value->addXdmItem(xdmItem);
374
                        return value;
375
     } else {
376
           
377
            exception = proc->checkAndCreateException(cppClass);
378
             } 
379
  }
380
  return nullptr;
381

    
382
}
383

    
384
    const char * XQueryProcessor::executeQueryToString(const char * infilename, const char * query){
385

    
386
 jmethodID mID = (jmethodID)SaxonProcessor::sxn_environ->env->GetMethodID (cppClass,"executeQueryToString", "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
387
 if (!mID) {
388
        std::cerr<<"Error: MyClassInDll."<<"executeQueryToString"<<" not found\n"<<std::endl;
389
    } else {
390
        jobjectArray stringArray = nullptr;
391
        jobjectArray objectArray = nullptr;
392

    
393
        int size = parameters.size() + properties.size();
394
        if(query!= nullptr) size++;
395
        if(infilename!= nullptr) size++;
396
        if(size >0) {
397
           int i=0;
398
           jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/Object");
399
           jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/String");
400
           objectArray = SaxonProcessor::sxn_environ->env->NewObjectArray( (jint)size, objectClass, 0 );
401
           stringArray = SaxonProcessor::sxn_environ->env->NewObjectArray( (jint)size, stringClass, 0 );
402

    
403
           if(query!= nullptr) {
404
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF("qs") );
405
                  SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF(query));
406
             i++;        
407
           }
408
           if(infilename!= nullptr) {
409
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF("s") );
410
                  SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF(infilename));
411
             i++;        
412
           }
413
           for(std::map<std::string, XdmValue* >::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter, i++) {
414
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF( (iter->first).c_str() ) );
415
                bool checkCast = SaxonProcessor::sxn_environ->env->IsInstanceOf((iter->second)->getUnderlyingValue(), lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/option/cpp/XdmValueForCpp") );
416
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, (jobject)((iter->second)->getUnderlyingValue()) );
417
           }
418
             for(std::map<std::string, std::string >::iterator iter=properties.begin(); iter!=properties.end(); ++iter, i++) {
419
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( stringArray, i, SaxonProcessor::sxn_environ->env->NewStringUTF( (iter->first).c_str()  ));
420
             SaxonProcessor::sxn_environ->env->SetObjectArrayElement( objectArray, i, (jobject)(SaxonProcessor::sxn_environ->env->NewStringUTF((iter->second).c_str())) );
421
           }
422
        }
423

    
424
          jstring result = (jstring)(SaxonProcessor::sxn_environ->env->CallObjectMethod(cppXQ, mID, SaxonProcessor::sxn_environ->env->NewStringUTF(cwdXQ.c_str()), stringArray, objectArray ));
425
          SaxonProcessor::sxn_environ->env->DeleteLocalRef(objectArray);
426
          SaxonProcessor::sxn_environ->env->DeleteLocalRef(stringArray);
427

    
428
          if(result) {
429
             const char * str = SaxonProcessor::sxn_environ->env->GetStringUTFChars(result, nullptr);
430
            //return "result should be ok";            
431
            return str;
432
           } else {
433
                    exception = proc->checkAndCreateException(cppClass);
434
                           
435
                     }
436
  }
437
  return nullptr;
438

    
439

    
440
    }
441

    
442

    
443
    const char * XQueryProcessor::runQueryToString(){
444
        return executeQueryToString(nullptr, nullptr);
445

    
446
    }
447

    
448

    
449
    XdmValue * XQueryProcessor::runQueryToValue(){
450
        return executeQueryToValue(nullptr, nullptr);
451
   }
452

    
453
    void XQueryProcessor::runQueryToFile(){
454
        executeQueryToFile(nullptr, nullptr, nullptr);
455
   }
456

    
457
    void XQueryProcessor::setQueryFile(const char * ofile){
458
           //outputfile1 = std::string(ofile); 
459
           setProperty("q", ofile);
460
    }
461

    
462
   void XQueryProcessor::setQueryContent(const char* content){
463
          // outputfile1 = std::string(content); 
464
           setProperty("qs", content);
465
  }
466

    
467

    
468

    
469
void XQueryProcessor::exceptionClear(){
470
        if(exception != nullptr) {
471
                delete exception;
472
                exception = nullptr;
473
                SaxonProcessor::sxn_environ->env->ExceptionClear();
474
        }
475

    
476
   
477
 
478
}
479

    
480
bool XQueryProcessor::exceptionOccurred(){
481
        return proc->exceptionOccurred();
482

    
483
}
484

    
485

    
486
const char * XQueryProcessor::getErrorCode() {
487
        if(exception == nullptr) {return nullptr;}
488
        return exception->getErrorCode();
489
}
490

    
491
const char * XQueryProcessor::getErrorMessage(){
492
        if(exception == nullptr) {return nullptr;}
493
        return exception->getMessage();
494
}
495

    
496
const char* XQueryProcessor::checkException(){
497
        /*if(proc->exception == nullptr) {
498
                proc->exception = proc->checkForException(SaxonProcessor::sxn_environ->env, cppClass, cppXQ);
499
        }
500
        return proc->exception;*/
501
        return proc->checkException();
502
}
503

    
504

    
505

    
506
SaxonApiException* XQueryProcessor::getException() {
507
    return exception;
508
}
(21-21/55)