Project

Profile

Help

Download (15.9 KB) Statistics
| Branch: | Revision:

he / src / main / c / Saxon.C.API / XPathProcessor.cpp @ a69dd173

1 72bf04c6 Norman Walsh
#include "XPathProcessor.h"
2
#include "XdmValue.h"
3
#include "XdmItem.h"
4
#include "XdmNode.h"
5
#include "XdmAtomicValue.h"
6 ead48a5d O'Neil Delpratt
#include "XdmFunctionItem.h"
7 72bf04c6 Norman Walsh
8
XPathProcessor::XPathProcessor() {
9
        SaxonProcessor *p = new SaxonProcessor(false);
10
        XPathProcessor(p, "");
11
}
12
13
XPathProcessor::XPathProcessor(SaxonProcessor* p, std::string curr) {
14
        proc = p;
15
16
        /*
17
         * Look for class.
18
         */
19
        cppClass = lookForClass(SaxonProcessor::sxn_environ->env,
20
                        "net/sf/saxon/option/cpp/XPathProcessor");
21 ead48a5d O'Neil Delpratt
        if ((proc->proc) == nullptr) {
22
                std::cerr << "Processor is nullptr" << std::endl;
23 72bf04c6 Norman Walsh
        }
24
25
        cppXP = createSaxonProcessor2(SaxonProcessor::sxn_environ->env, cppClass,
26
                        "(Lnet/sf/saxon/s9api/Processor;)V", proc->proc);
27
28
29
30
#ifdef DEBUG
31
        jmethodID debugMID = SaxonProcessor::sxn_environ->env->GetStaticMethodID(cppClass, "setDebugMode", "(Z)V");
32
        SaxonProcessor::sxn_environ->env->CallStaticVoidMethod(cppClass, debugMID, (jboolean)true);
33
#endif    
34
35 ead48a5d O'Neil Delpratt
        exception = nullptr;
36 72bf04c6 Norman Walsh
        if(!(proc->cwd.empty()) && curr.empty()){
37
                cwdXP = proc->cwd;
38
        } else {
39
                cwdXP = curr;
40
        }
41
42
}
43
44
XdmValue * XPathProcessor::evaluate(const char * xpathStr) {
45 ead48a5d O'Neil Delpratt
        if (xpathStr == nullptr) {
46
                std::cerr << "Error:: XPath string cannot be empty or nullptr" << std::endl;
47
        return nullptr;
48 72bf04c6 Norman Walsh
}
49 ead48a5d O'Neil Delpratt
50 72bf04c6 Norman Walsh
jmethodID mID =
51
                (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(cppClass, "evaluate",
52
                                "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;)[Lnet/sf/saxon/s9api/XdmValue;");
53
if (!mID) {
54
        std::cerr << "Error: "<<getDllname() << ".evaluate" << " not found\n"
55
                        << std::endl;
56
57
} else {
58 ead48a5d O'Neil Delpratt
        jobjectArray stringArray = nullptr;
59
        jobjectArray objectArray = nullptr;
60 72bf04c6 Norman Walsh
        jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/Object");
61
        jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/String");
62
63
        int size = parameters.size() + properties.size();
64
65
        if (size > 0) {
66
                objectArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
67
                                objectClass, 0);
68
                stringArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
69
                                stringClass, 0);
70
                int i = 0;
71
                for (std::map<std::string, XdmValue*>::iterator iter = parameters.begin();
72
                                iter != parameters.end(); ++iter, i++) {
73
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(stringArray, i,
74
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->first).c_str()));
75
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(objectArray, i,
76
                                        (iter->second)->getUnderlyingValue());
77
                }
78
                for (std::map<std::string, std::string>::iterator iter = properties.begin();
79
                                iter != properties.end(); ++iter, i++) {
80
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(stringArray, i,
81
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->first).c_str()));
82
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(objectArray, i,
83
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->second).c_str()));
84
                }
85
        } 
86
        jobjectArray results = (jobjectArray)(
87
                        SaxonProcessor::sxn_environ->env->CallObjectMethod(cppXP, mID,
88
                                        SaxonProcessor::sxn_environ->env->NewStringUTF(cwdXP.c_str()),
89
                                        SaxonProcessor::sxn_environ->env->NewStringUTF(xpathStr), stringArray, objectArray));
90
        if(!results) {
91
                exception = proc->checkAndCreateException(cppClass);
92 ead48a5d O'Neil Delpratt
                return nullptr;
93 72bf04c6 Norman Walsh
        }
94
        
95
        int sizex = SaxonProcessor::sxn_environ->env->GetArrayLength(results);
96
        if (size > 0) {
97
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(stringArray);
98
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(objectArray);
99
        }
100
        if (sizex>0) {
101
                jclass atomicValueClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmAtomicValue");
102
                jclass nodeClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmNode");
103
                jclass functionItemClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmFunctionItem");
104
105
                XdmValue * value = new XdmValue();
106 ead48a5d O'Neil Delpratt
                XdmItem * xdmItem = nullptr;
107 72bf04c6 Norman Walsh
                for (int p=0; p < sizex; ++p) 
108
                {
109
                        jobject resulti = SaxonProcessor::sxn_environ->env->GetObjectArrayElement(results, p);
110
                        //value->addUnderlyingValue(resulti);
111
112
                        if(SaxonProcessor::sxn_environ->env->IsInstanceOf(resulti, atomicValueClass)           == JNI_TRUE) {
113
                                xdmItem = new XdmAtomicValue(resulti);
114
115
                        } else if(SaxonProcessor::sxn_environ->env->IsInstanceOf(resulti, nodeClass)           == JNI_TRUE) {
116
                                xdmItem = new XdmNode(resulti);
117
118
                        } else if (SaxonProcessor::sxn_environ->env->IsInstanceOf(resulti, functionItemClass)           == JNI_TRUE) {
119
                                xdmItem =  new XdmFunctionItem(resulti);
120
                        }
121
                        if(sizex == 1) {
122
                                value->decrementRefCount();
123
                                delete value;
124
                                SaxonProcessor::sxn_environ->env->DeleteLocalRef(results);
125
                                return xdmItem;                
126
                        }
127
                        
128
                        value->addXdmItem(xdmItem);
129
                }
130
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(results);
131
                return value;
132
        }
133
}
134 ead48a5d O'Neil Delpratt
return nullptr;
135 72bf04c6 Norman Walsh
136
}
137
138
XdmItem * XPathProcessor::evaluateSingle(const char * xpathStr) {
139 ead48a5d O'Neil Delpratt
        if (xpathStr == nullptr) {
140
                std::cerr << "Error:: XPath string cannot be empty or nullptr" << std::endl;
141
             return nullptr;
142 72bf04c6 Norman Walsh
        }
143 ead48a5d O'Neil Delpratt
144 72bf04c6 Norman Walsh
jmethodID mID =
145
                (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(cppClass, "evaluateSingle",
146
                                "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;)Lnet/sf/saxon/s9api/XdmItem;");
147
if (!mID) {
148
        std::cerr << "Error: MyClassInDll." << "evaluateSingle" << " not found\n"
149
                        << std::endl;
150
151
} else {
152 ead48a5d O'Neil Delpratt
        jobjectArray stringArray = nullptr;
153
        jobjectArray objectArray = nullptr;
154 72bf04c6 Norman Walsh
        jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/Object");
155
        jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/String");
156
157
        int size = parameters.size() + properties.size();
158
#ifdef DEBUG
159
                std::cerr<<"Properties size: "<<properties.size()<<std::endl;
160
                std::cerr<<"Parameter size: "<<parameters.size()<<std::endl;
161
                std::cerr<<"size:"<<size<<std::endl;
162
#endif
163
        if (size > 0) {
164
                objectArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
165
                                objectClass, 0);
166
                stringArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
167
                                stringClass, 0);
168
                int i = 0;
169
                for (std::map<std::string, XdmValue*>::iterator iter = parameters.begin();
170
                                iter != parameters.end(); ++iter, i++) {
171
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(stringArray, i,
172
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->first).c_str()));
173
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(objectArray, i,
174
                                        (iter->second)->getUnderlyingValue());
175
#ifdef DEBUG
176
                                std::string s1 = typeid(iter->second).name();
177
                                std::cerr<<"Type of itr:"<<s1<<std::endl;
178
                                jobject xx = (iter->second)->getUnderlyingValue();
179 ead48a5d O'Neil Delpratt
                                if(xx == nullptr) {
180 72bf04c6 Norman Walsh
                                        std::cerr<<"value failed"<<std::endl;
181
                                } else {
182
183
                                        std::cerr<<"Type of value:"<<(typeid(xx).name())<<std::endl;
184
                                }
185 ead48a5d O'Neil Delpratt
                                if((iter->second)->getUnderlyingValue() == nullptr) {
186
                                        std::cerr<<"(iter->second)->getUnderlyingValue() is nullptr"<<std::endl;
187 72bf04c6 Norman Walsh
                                }
188
#endif
189
                }
190
                for (std::map<std::string, std::string>::iterator iter = properties.begin();
191
                                iter != properties.end(); ++iter, i++) {
192
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(stringArray, i,
193
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->first).c_str()));
194
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(objectArray, i,
195
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->second).c_str()));
196
                }
197
        }
198
        jobject result = (jobject)(
199
                        SaxonProcessor::sxn_environ->env->CallObjectMethod(cppXP, mID,
200
                                        SaxonProcessor::sxn_environ->env->NewStringUTF(cwdXP.c_str()),
201
                                        SaxonProcessor::sxn_environ->env->NewStringUTF(xpathStr), stringArray, objectArray));
202
        if (size > 0) {
203
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(stringArray);
204
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(objectArray);
205
        }
206
        if (result) {
207
                jclass atomicValueClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmAtomicValue");
208
                jclass nodeClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmNode");
209
                jclass functionItemClass = lookForClass(SaxonProcessor::sxn_environ->env, "net/sf/saxon/s9api/XdmFunctionItem");
210 ead48a5d O'Neil Delpratt
                XdmItem * xdmItem = nullptr;
211 72bf04c6 Norman Walsh
                if(SaxonProcessor::sxn_environ->env->IsInstanceOf(result, atomicValueClass)           == JNI_TRUE) {
212
                        xdmItem = new XdmAtomicValue(result);
213
214
                } else if(SaxonProcessor::sxn_environ->env->IsInstanceOf(result, nodeClass)           == JNI_TRUE) {
215
                        
216
                        xdmItem = new XdmNode(result);
217
218
                } else if (SaxonProcessor::sxn_environ->env->IsInstanceOf(result, functionItemClass)           == JNI_TRUE) {
219 ead48a5d O'Neil Delpratt
                        return nullptr;
220 72bf04c6 Norman Walsh
                }
221
                //SaxonProcessor::sxn_environ->env->DeleteLocalRef(result);
222
                return xdmItem;
223
        } else  {
224
                        exception = proc->checkAndCreateException(cppClass);
225
                           
226
                     }
227
}
228
229 ead48a5d O'Neil Delpratt
return nullptr;
230 72bf04c6 Norman Walsh
231
}
232
233
void XPathProcessor::setContextItem(XdmItem * item) {
234
        contextItem = item;
235 ead48a5d O'Neil Delpratt
            if(item != nullptr){
236 72bf04c6 Norman Walsh
              parameters["node"] = (XdmValue *)item;
237
            }
238
}
239
240
void XPathProcessor::setContextFile(const char * filename) {
241 ead48a5d O'Neil Delpratt
        if (filename != nullptr) {
242 72bf04c6 Norman Walsh
                setProperty("s", filename);
243
        }
244
}
245
246
247
void XPathProcessor::declareNamespace(const char *prefix, const char * uri){
248 ead48a5d O'Neil Delpratt
        if (prefix == nullptr || uri == nullptr) {
249 72bf04c6 Norman Walsh
                return;
250
        }
251
        jmethodID mID =
252
                (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(cppClass, "declareNamespace",
253
                                "(Ljava/lang/String;Ljava/lang/String;)V");
254
        if (!mID) {
255
        std::cerr << "Error: "<<getDllname() << ".declareNameSpace" << " not found\n"
256
                        << std::endl;
257
258
        } else {
259
                SaxonProcessor::sxn_environ->env->CallObjectMethod(cppXP, mID,
260
                                SaxonProcessor::sxn_environ->env->NewStringUTF(prefix),
261
                                SaxonProcessor::sxn_environ->env->NewStringUTF(uri));
262
                //proc->checkAndCreateException(cppClass);
263
        }
264
265
}
266
267
#if CVERSION_API_NO >= 121
268
269
270
void XPathProcessor::setBackwardsCompatible(bool option) {
271
    if (option) {
272
                        setProperty("backwardsCom:", "true");
273
    } else {
274
       properties.erase("backwardsCom:");
275
    }
276
}
277
278
void XPathProcessor::setCaching(bool caching){
279
    if (caching) {
280
                setProperty("caching:", "true");
281
    } else {
282
       properties.erase("caching:");
283
    }
284
285
}
286
287
void XPathProcessor::importSchemaNamespace(const char* uri){
288 ead48a5d O'Neil Delpratt
      if (uri != nullptr) {
289 72bf04c6 Norman Walsh
                       setProperty("importSN", uri);
290
      }
291
}
292
293
294
#endif
295
296
297
void XPathProcessor::setBaseURI(const char * uriStr) {
298 ead48a5d O'Neil Delpratt
        if (uriStr == nullptr) {
299
                std::cerr << "Error:: XPath string cannot be empty or nullptr" << std::endl;
300 72bf04c6 Norman Walsh
             return;
301
        }
302 ead48a5d O'Neil Delpratt
303 72bf04c6 Norman Walsh
jmethodID mID =
304
                (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(cppClass, "setBaseURI",
305
                                "(Ljava/lang/String;)V");
306
if (!mID) {
307
        std::cerr << "Error: Saxonc." << "setBaseURI" << " not found\n"
308
                        << std::endl;
309
310
} else {
311
312
        SaxonProcessor::sxn_environ->env->CallObjectMethod(cppXP, mID,
313
                                        SaxonProcessor::sxn_environ->env->NewStringUTF(uriStr));
314
}
315
316
}
317
318
bool XPathProcessor::effectiveBooleanValue(const char * xpathStr) {
319 ead48a5d O'Neil Delpratt
        if (xpathStr == nullptr) {
320
                std::cerr << "Error:: XPath string cannot be empty or nullptr" << std::endl;
321 72bf04c6 Norman Walsh
             return false;
322
        }
323 ead48a5d O'Neil Delpratt
324 72bf04c6 Norman Walsh
jmethodID mID =
325
                (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(cppClass, "effectiveBooleanValue",
326
                                "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;)Z");
327
if (!mID) {
328
        std::cerr << "Error: MyClassInDll." << "effectiveBooleanValue" << " not found\n"<< std::endl;
329
330
} else {
331 ead48a5d O'Neil Delpratt
        jobjectArray stringArray = nullptr;
332
        jobjectArray objectArray = nullptr;
333 72bf04c6 Norman Walsh
        jclass objectClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/Object");
334
        jclass stringClass = lookForClass(SaxonProcessor::sxn_environ->env, "java/lang/String");
335
336
        int size = parameters.size() + properties.size();
337
        if (size > 0) {
338
                objectArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
339
                                objectClass, 0);
340
                stringArray = SaxonProcessor::sxn_environ->env->NewObjectArray((jint) size,
341
                                stringClass, 0);
342
                int i = 0;
343
                for (std::map<std::string, XdmValue*>::iterator iter = parameters.begin();
344
                                iter != parameters.end(); ++iter, i++) {
345
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(stringArray, i,
346
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->first).c_str()));
347
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(objectArray, i,
348
                                        (iter->second)->getUnderlyingValue());
349
                }
350
                for (std::map<std::string, std::string>::iterator iter = properties.begin();
351
                                iter != properties.end(); ++iter, i++) {
352
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(stringArray, i,
353
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->first).c_str()));
354
                        SaxonProcessor::sxn_environ->env->SetObjectArrayElement(objectArray, i,
355
                                        SaxonProcessor::sxn_environ->env->NewStringUTF((iter->second).c_str()));
356
                }
357
        }
358
        jboolean result = (jboolean)(
359
                        SaxonProcessor::sxn_environ->env->CallBooleanMethod(cppXP, mID,
360
                                        SaxonProcessor::sxn_environ->env->NewStringUTF(cwdXP.c_str()),
361
                                        SaxonProcessor::sxn_environ->env->NewStringUTF(xpathStr), stringArray, objectArray));
362
        if (size > 0) {
363
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(stringArray);
364
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(objectArray);
365
        }
366
        exception = proc->checkAndCreateException(cppClass);
367
        return result;
368
}
369
return false;
370
}
371
372
void XPathProcessor::setParameter(const char * name, XdmValue* value) {
373 ead48a5d O'Neil Delpratt
        if(value != nullptr){
374 72bf04c6 Norman Walsh
                value->incrementRefCount();
375
                int s = parameters.size();
376
                std::string skey = "param:"+std::string(name);
377
                parameters[skey] = value;
378
                if(s == parameters.size()) {
379
            std::map<std::string, XdmValue*>::iterator it;
380
            it = parameters.find(skey);
381
            if (it != parameters.end()) {
382
                XdmValue * valuei = it->second;
383
                valuei->decrementRefCount();
384 ead48a5d O'Neil Delpratt
                if(valuei != nullptr && valuei->getRefCount() < 1){
385 72bf04c6 Norman Walsh
                    delete value;
386
                }
387
                parameters.erase(skey);
388
                parameters[skey] = value;
389
            }
390
                }
391
        }
392
}
393
394
bool XPathProcessor::removeParameter(const char * name) {
395
        return (bool)(parameters.erase("param:"+std::string(name)));
396
}
397
398
void XPathProcessor::setProperty(const char * name, const char * value) {
399 ead48a5d O'Neil Delpratt
        if(name != nullptr) {
400 72bf04c6 Norman Walsh
            int s = properties.size();
401
                std::string skey = std::string(name);
402 ead48a5d O'Neil Delpratt
                properties.insert(std::pair<std::string, std::string>(skey, std::string((value == nullptr ? "" : value))));
403 72bf04c6 Norman Walsh
404
                if(s == properties.size()) {
405
            std::map<std::string, std::string>::iterator it;
406
            it = properties.find(skey);
407
            if (it != properties.end()) {
408
                properties.erase(skey);
409 ead48a5d O'Neil Delpratt
                properties[skey] = std::string((value == nullptr ? "" : value));
410 72bf04c6 Norman Walsh
            }
411
                }
412
        }
413
}
414
415
void XPathProcessor::clearParameters(bool delVal) {
416
        if(delVal){
417
                       for(std::map<std::string, XdmValue*>::iterator itr = parameters.begin(); itr != parameters.end(); itr++){
418
                        XdmValue * value = itr->second;
419
                        value->decrementRefCount();
420
#ifdef DEBUG
421
                        std::cerr<<"XPathProc.clearParameter() - XdmValue refCount="<<value->getRefCount()<<std::endl;
422
#endif
423 ead48a5d O'Neil Delpratt
                        if(value != nullptr && value->getRefCount() < 1){
424 72bf04c6 Norman Walsh
                                delete value;
425
                        }
426
                }
427
                parameters.clear();
428
        }
429
}
430
431
void XPathProcessor::clearProperties() {
432
        properties.clear();
433
}
434
435
436
   void XPathProcessor::setcwd(const char* dir){
437
    cwdXP = std::string(dir);
438
   }
439
440
std::map<std::string,XdmValue*>& XPathProcessor::getParameters(){
441
        std::map<std::string,XdmValue*>& ptr = parameters;
442
        return ptr;
443
}
444
445
std::map<std::string,std::string>& XPathProcessor::getProperties(){
446
        std::map<std::string,std::string> &ptr = properties;
447
        return ptr;
448
}
449
450
void XPathProcessor::exceptionClear(){
451 ead48a5d O'Neil Delpratt
        if(exception != nullptr) {
452 72bf04c6 Norman Walsh
                delete proc->exception;
453 ead48a5d O'Neil Delpratt
                exception = nullptr;
454 72bf04c6 Norman Walsh
        }
455
456
   SaxonProcessor::sxn_environ->env->ExceptionClear();
457
 
458
}
459
460
const char * XPathProcessor::getErrorCode() {
461 ead48a5d O'Neil Delpratt
        if(exception == nullptr) {return nullptr;}
462 72bf04c6 Norman Walsh
        return exception->getErrorCode();
463
}
464
465
const char * XPathProcessor::getErrorMessage(){
466 ead48a5d O'Neil Delpratt
        if(exception == nullptr) {return nullptr;}
467 79d12c83 O'Neil Delpratt
        return exception->getMessage();
468
}
469
470
    SaxonApiException * XPathProcessor::getException() {
471
        return exception;
472
473 72bf04c6 Norman Walsh
}
474
475
    bool XPathProcessor::exceptionOccurred(){
476
        return proc->exceptionOccurred();
477
    }
478
479
480
481
    const char* XPathProcessor::checkException(){
482
        return proc->checkException(cppXP);
483
    }