Project

Profile

Help

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

he / latest9.6 / hec / Saxon.C.API / 64-bit-code / EEC / SaxonCGlue.c @ fa554ba5

1
#include "SaxonCGlue.h"
2

    
3
jobject cpp;
4
/*
5
 * Set Dll name. Also set the saxon resources directory.
6
 * If the SAXONC_HOME sxnc_environmental variable is set then use that as base.
7
 */
8
void setDllname(){
9
    size_t name_len  = strlen(tempDllname);
10
    size_t rDir_len  = strlen(tempResources_dir);
11
    char * env = getenv("SAXONC_HOME");
12
    size_t env_len;
13
    if(env!= NULL) {
14
        
15
        
16
        env_len = strlen(env);
17
        dllname =malloc(sizeof(char)*name_len+env_len+1);
18
        resources_dir =malloc(sizeof(char)*rDir_len+env_len+1);
19
        snprintf(dllname, env_len+name_len+1, "%s%s", env, tempDllname);
20
        snprintf(resources_dir, env_len+rDir_len+1, "%s%s", env, tempResources_dir);
21
        
22
#ifdef DEBUG
23
        
24
        printf("envDir: %s\n", env);
25
        
26
        
27
#endif
28
        
29
    } else {
30
#ifdef __linux__
31
        env_len = 8;
32
#elif  defined (__APPLE__) && defined(__MACH__)
33
        env_len = 14;
34
#else
35
        enc_len = 8; //not used under windows
36
#endif
37
        dllname =malloc(sizeof(char)*name_len+env_len+1);
38
        resources_dir =malloc(sizeof(char)*rDir_len+env_len+1);
39
#ifdef DEBUG
40
        if(dllname == NULL || resources_dir == NULL)
41
        {
42
            // error
43
            printf("Error in allocation of Dllname\n");
44
        }
45
#endif
46
        memset(&dllname[0], 0, sizeof(dllname));
47
        memset(&resources_dir[0], 0, sizeof(resources_dir));
48
#ifdef __linux__
49
        
50
        snprintf(dllname, 10+name_len+1, "%s%s", "/usr/lib64", tempDllname);
51
        snprintf(resources_dir, 10+rDir_len+1, "%s%s", "/usr/lib64", tempResources_dir);
52
#elif  defined (__APPLE__) && defined(__MACH__)
53
        snprintf(dllname, 14+name_len+1, "%s%s", "/usr/local/lib", tempDllname);
54
        snprintf(resources_dir, 14+rDir_len+1, "%s%s", "/usr/local/lib", tempResources_dir);
55
#else
56
        //TODO When windows version of Saxon/C is done we will have to fixup this
57
        strncpy(dllname, "C:\\Program Files\\Saxonica\\SaxonEEC1.0.1", 42);
58
        strncpy(resources_dir, "C:\\Program Files\\Saxonica\\SaxonEEC1.0.1", 42);
59
#endif
60
        
61
        
62
        
63
    }
64
    
65
    
66
#ifdef DEBUG
67
    
68
    printf("Library length: %i\n", name_len);
69
    printf("Env length: %i\n", env_len);
70
    printf("dllname length alloc: %i\n", (env_len+name_len+1));
71
    printf("resources length alloc: %i\n", (env_len+rDir_len+1));
72
    printf("size of dllname %i\n", strlen(dllname));
73
    printf("dllName: %s\n", dllname);
74
    printf("resources_dir: %s\n", resources_dir);
75
    printf("size of resources dir %i\n", strlen(resources_dir));
76
#endif
77
    
78
}
79

    
80
char * getDllname(){
81
    return dllname;
82
}
83

    
84
char * getResourceDirectory(){
85
    return resources_dir;
86
}
87

    
88
/*
89
 * Load dll using the default setting in Saxon/C
90
 * Recommended method to use to load library
91
 */
92
HANDLE loadDefaultDll(){
93
    return loadDll(NULL);
94
}
95

    
96

    
97
/*
98
 * Load dll.
99
 */
100
HANDLE loadDll(char* name)
101
{
102
    if(name == NULL) {
103
        setDllname();
104
        name = getDllname();
105
        //perror("Error1: ");
106
    }
107
    
108
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
109
    HANDLE hDll = LoadLibrary (_T(name)); // Used for windows only
110
#else
111
    HANDLE hDll = LoadLibrary(name);
112
#endif
113
    
114
    if (!hDll) {
115
        fprintf (stderr, "Unable to load %s\n", name);
116
        perror("Error: ");
117
        exit(1);
118
    }
119
#ifdef DEBUG
120
    fprintf (stderr, "%s loaded\n", name);
121
#endif
122
    
123
    return hDll;
124
}
125

    
126

    
127

    
128
jint (JNICALL * JNI_GetDefaultJavaVMInitArgs_func) (void *args);
129
jint (JNICALL * JNI_CreateJavaVM_func) (JavaVM **pvm, void **penv, void *args);
130

    
131

    
132

    
133
void initDefaultJavaRT(sxnc_environment ** env){
134
    sxnc_environment *environ = *env;
135
    initJavaRT((environ->myDllHandle), &(environ->jvm), &(environ->env));
136
}
137

    
138
/*
139
 * Initialize JET run-time.
140
 */
141
void initJavaRT(HANDLE myDllHandle, JavaVM** pjvm, JNIEnv** penv)
142
{
143
    if(jvmCreated==0) {
144
        jvmCreated=1;
145
#ifdef DEBUG
146
        perror ("initJavaRT - load Saxon/C library\n");
147
#endif
148
        int result;
149
        JavaVMInitArgs args;
150
        JNI_GetDefaultJavaVMInitArgs_func =
151
        (jint (JNICALL *) (void *args))
152
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
153
        GetProcAddress ((HMODULE)myDllHandle, "JNI_GetDefaultJavaVMInitArgs");
154
#else
155
        GetProcAddress (myDllHandle, "JNI_GetDefaultJavaVMInitArgs");
156
#endif
157
        
158
        
159
        JNI_CreateJavaVM_func =
160
        (jint (JNICALL *) (JavaVM **pvm, void **penv, void *args))
161
        
162
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
163
        GetProcAddress ((HMODULE)myDllHandle, "JNI_CreateJavaVM");
164
#else
165
        GetProcAddress (myDllHandle, "JNI_CreateJavaVM");
166
        
167
#endif
168
        
169
        
170
        if(!JNI_GetDefaultJavaVMInitArgs_func) {
171
            fprintf (stderr,"%s doesn't contain public JNI_GetDefaultJavaVMInitArgs\n", getDllname());
172
            exit (1);
173
        }
174
        
175
        if(!JNI_CreateJavaVM_func) {
176
            fprintf (stderr,"%s doesn't contain public JNI_CreateJavaVM\n", getDllname());
177
            exit (1);
178
        }
179
        
180
        memset (&args, 0, sizeof(args));
181
        
182
        args.version = JNI_VERSION_1_2;
183
        result = JNI_GetDefaultJavaVMInitArgs_func(&args);
184
        if (result != JNI_OK) {
185
            fprintf(stderr,"JNI_GetDefaultJavaVMInitArgs() failed with result\n");
186
            exit(1);
187
        }
188
        
189
        /*
190
         * NOTE: no JVM is actually created
191
         * this call to JNI_CreateJavaVM is intended for JET RT initialization
192
         */
193
        result = JNI_CreateJavaVM_func (pjvm, (void **)penv, &args);
194
        if (result != JNI_OK) {
195
            fprintf(stderr,"JNI_CreateJavaVM() failed with result: %i\n",result);
196
            exit(1);
197
        }
198
        
199
        
200
        fflush (stdout);
201
    } else {
202
#ifdef DEBUG
203
        perror ("initJavaRT - Saxon/C library loaded already\n");
204
#endif
205
    }
206
}
207

    
208

    
209
/*
210
 * Look for class.
211
 */
212
jclass lookForClass (JNIEnv* penv, const char* name)
213
{
214
    jclass clazz = (*penv)->FindClass (penv, name);
215
    
216
    if (!clazz) {
217
        printf("Unable to find class %s\n", name);
218
        return NULL;
219
    }
220
#ifdef DEBUG
221
    printf ("Class %s found\n", name);
222
    fflush (stdout);
223
#endif
224
    
225
    return clazz;
226
}
227

    
228

    
229
/*
230
 * Create an object and invoke the instance method
231
 */
232
void invokeInstanceMethod (JNIEnv* penv, jclass myClassInDll, char * name, char * arguments)
233
{
234
    jmethodID MID_init, MID_name;
235
    jobject obj;
236
    
237
    MID_init = (*penv)->GetMethodID (penv, myClassInDll, "<init>", "()V");
238
    if (!MID_init) {
239
        printf("Error: MyClassInDll.<init>() not found\n");
240
        return;
241
    }
242
    
243
    obj = (*penv)->NewObject(penv, myClassInDll, MID_init);
244
    if (!obj) {
245
        printf("Error: failed to allocate an object\n");
246
        return;
247
    }
248
    
249
    MID_name = (*penv)->GetMethodID (penv, myClassInDll, name, arguments);
250
    
251
    if (!MID_name) {
252
        printf("Error: %s not found\n", name);
253
        return;
254
    }
255
    
256
    (*(penv))->CallVoidMethod (penv, obj, MID_name);
257
}
258

    
259

    
260

    
261

    
262
/*
263
 * Invoke the static method
264
 */
265
void invokeStaticMethod(JNIEnv* penv, jclass myClassInDll, char* name, char* arguments)
266
{
267
    jmethodID MID_name;
268
    
269
    MID_name = (*penv)->GetStaticMethodID(penv, myClassInDll, name, arguments);
270
    if (!MID_name) {
271
        printf("\nError: method %s not found\n", name);
272
        return;
273
    }
274
    
275
    (*penv)->CallStaticVoidMethod(penv, myClassInDll, MID_name);
276
}
277

    
278

    
279
/*
280
 * Find a constructor with a set arguments
281
 */
282
jmethodID findConstructor (JNIEnv* penv, jclass myClassInDll, char* arguments)
283
{
284
    jmethodID MID_initj;
285
    jobject obj;
286
    
287
    MID_initj = (jmethodID)(*penv)->GetMethodID (penv, myClassInDll, "<init>", arguments);
288
    if (!MID_initj) {
289
        printf("Error: MyClassInDll.<init>() not found\n");
290
        fflush (stdout);
291
        return 0;
292
    }
293
    
294
    return MID_initj;
295
}
296

    
297
/*
298
 * Create the Java SaxonProcessor
299
 */
300
jobject createSaxonProcessor (JNIEnv* penv, jclass myClassInDll, const char * arguments, jobject argument1, jboolean license)
301
{
302
    jmethodID MID_initi;
303
    
304
    jobject obj;
305
    
306
    MID_initi = (jmethodID)(*(penv))->GetMethodID (penv, myClassInDll, "<init>", arguments);
307
    if (!MID_initi) {
308
        printf("Error: MyClassInDll.<init>() not found\n");
309
        return NULL;
310
    }
311
    
312
    if(argument1) {
313
        
314
        obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi, argument1, license);
315
    } else {
316
        
317
        obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi, license);
318
    }
319
    if (!obj) {
320
        printf("Error: failed to allocate an object\n");
321
        return NULL;
322
    }
323
    return obj;
324
}
325

    
326

    
327
/*
328
 * Create the Java SaxonProcessor without boolean license argument
329
 */
330
jobject createSaxonProcessor2 (JNIEnv* penv, jclass myClassInDll, const char * arguments, jobject argument1)
331
{
332
    jmethodID MID_initi;
333
    
334
    jobject obj;
335
    
336
    MID_initi = (jmethodID)(*(penv))->GetMethodID (penv, myClassInDll, "<init>", arguments);
337
    if (!MID_initi) {
338
        printf("Error: MyClassInDll.<init>() not found\n");
339
        return NULL;
340
    }
341
    
342
    if(argument1) {
343
        
344
        obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi, argument1);
345
    } else {
346
        
347
        obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi);
348
    }
349
    if (!obj) {
350
        printf("Error: failed to allocate an object\n");
351
        return NULL;
352
    }
353
    return obj;
354
}
355

    
356

    
357
/*
358
 * Callback to check for exceptions. When called it returns the exception as a string
359
 */
360
const char * checkForException(sxnc_environment environ, jclass callingClass,  jobject callingObject){
361
    
362
    if ((*(environ.env))->ExceptionCheck(environ.env)) {
363
        
364
        jthrowable exc = (*(environ.env))->ExceptionOccurred(environ.env);
365
#ifdef DEBUG
366
        (*(environ.env))->ExceptionDescribe(environ.env);
367
#endif
368
        if(exc) {
369
            printf("Exception Occurred!");
370
        }
371
        jclass exccls = (jclass) (*(environ.env))->GetObjectClass(environ.env, exc);
372
        
373
        jclass clscls = (jclass) (*(environ.env))->FindClass(environ.env, "java/lang/Class");
374
        
375
        jmethodID getName = (jmethodID)(*(environ.env))->GetMethodID(environ.env, clscls, "getName", "()Ljava/lang/String;");
376
        jstring name = (jstring)((*(environ.env))->CallObjectMethod(environ.env, exccls, getName));
377
        char const* utfName = (*(environ.env))->GetStringUTFChars(environ.env, name, NULL);
378
        
379
        if(callingObject != NULL && strcmp(utfName, "net.sf.saxon.s9api.SaxonApiException") == 0){
380
            
381
            jclass saxonExcClass = (*(environ.env))->FindClass(environ.env, "java/lang/Throwable");
382
            
383
            jmethodID  getMessage =  (jmethodID)(*(environ.env))->GetMethodID(environ.env, exccls, "getMessage", "()Ljava/lang/String;");
384
            
385
            if(getMessage) {
386
                
387
                jstring message = (jstring)((*(environ.env))->CallObjectMethod(environ.env, exc, getMessage));
388
                
389
                if(!message){
390
                    
391
                    (*(environ.env))->ExceptionClear(environ.env);
392
                    return 0;
393
                }
394
                char const* utfMessage= (*(environ.env))->GetStringUTFChars(environ.env, message, NULL);
395
                
396
                if(utfMessage != NULL) {
397
                    (*(environ.env))->ReleaseStringUTFChars(environ.env, name, utfName);
398
                }
399
                
400
                (*(environ.env))->ExceptionClear(environ.env);
401
                return utfMessage;
402
            }
403
        }
404
        (*(environ.env))->ReleaseStringUTFChars(environ.env, name, utfName);
405
    }
406
    (*(environ.env))->ExceptionClear(environ.env);
407
    return NULL;
408
}
409

    
410

    
411
/*
412
 * Clean up and destroy Java VM to release memory used.
413
 */
414
void finalizeJavaRT (JavaVM* jvm)
415
{
416
    
417
    if(jvmCreated!= 0){
418
        (*jvm)->DestroyJavaVM (jvm);
419
        jvmCreated=0;
420
    }
421
}
422

    
423

    
424
/*
425
 * Get a parameter from list
426
 */
427
jobject getParameter(sxnc_parameter *parameters,  int parLen, const char* namespacei, const char * name){
428
    int i =0;
429
    for(i =0; i< parLen;i++) {
430
        if(strcmp(parameters[i].name, name) == 0)
431
        return (jobject)parameters[i].value;
432
    }
433
    return NULL;
434
}
435

    
436

    
437
/*
438
 * Get a property from list
439
 */
440
char* getProperty(sxnc_property * properties, int propLen, const char* namespacei, const char * name){
441
    int i =0;
442
    for(i =0; i< propLen;i++) {
443
        if(strcmp(properties[i].name, name) == 0)
444
        return properties[i].value;
445
    }
446
    return 0;
447
}
448

    
449

    
450
/*
451
 * set a parameter
452
 */
453
void setParameter(sxnc_parameter **parameters, int * parLen, int * parCap, const char * namespacei, const char * name, jobject value){
454
    
455
    if(getParameter(*parameters, (*parLen), "", name) != 0){
456
        return;
457
    }
458
    (*parLen)++;
459
    if((*parLen) >= (*parCap)) {
460
        (*parCap) *=2;
461
        sxnc_parameter* temp = (sxnc_parameter*)malloc(sizeof(sxnc_parameter)*(*parCap));
462
        int i =0;
463
        for(i =0; i< (*parLen)-1;i++) {
464
            temp[i] = (*parameters)[i];
465
        }
466
        free(parameters);
467
        parameters = &temp;
468
    }
469
    int nameLen = strlen(name)+7;
470
    char *newName = malloc(sizeof(char)*nameLen);
471
    snprintf(newName, nameLen, "%s%s", "param:", name );
472
    (*parameters)[(*parLen)-1].name = (char*)newName;
473
    (*parameters)[(*parLen)-1].value = (jobject)value;
474
}
475

    
476

    
477
/*
478
 * set a property
479
 */
480
void setProperty(sxnc_property ** properties, int *propLen, int *propCap, const char* name, const char* value){
481
    if(getProperty(*properties, (*propLen), "", name) != 0){
482
        return;
483
    }
484
    
485
    if(((*propLen)+1) >= (*propCap)) {
486
        (*propCap) *=2;
487
        sxnc_property* temp = (sxnc_property*)malloc(sizeof(sxnc_property)*  (*propCap));
488
        int i =0;
489
        for(i =0; i< (*propLen)-1;i++) {
490
            temp[i] = (*properties)[i];
491
        }
492
        free(properties);
493
        properties = &temp;
494
        
495
    }
496
    int nameLen = strlen(name)+1;
497
    char *newName = (char*)malloc(sizeof(char)*nameLen);
498
    snprintf(newName, nameLen, "%s", name );
499
    char *newValue = (char*)malloc(sizeof(char)*strlen(value)+1);
500
    snprintf(newValue, strlen(value)+1, "%s", value );
501
    (*properties)[(*propLen)].name = (char*)newName;
502
    (*properties)[(*propLen)].value = (char*)newValue;
503
    (*propLen)++;
504
}
505

    
506
/*
507
 * clear parameter
508
 */
509
void clearSettings(sxnc_parameter **parameters, int *parLen, sxnc_property ** properties, int *propLen){
510
    int i =0;
511
    free(*parameters);
512
    free(*parameters);
513
    /*for(i =0; i< parLen; i++){
514
     free((*parameters[i].name);
515
     free(parameters[i].value);
516
     }
517
     for(i =0; i< propLen; i++){
518
     free(properties[i].name);
519
     free(properties[i].value);
520
     }*/
521
    
522
    *parameters = (sxnc_parameter *)calloc(10, sizeof(sxnc_parameter));
523
    *properties = (sxnc_property *)calloc(10, sizeof(sxnc_property));
524
    (*parLen) = 0;
525
    (*propLen) = 0;
526
}
527

    
528

    
529
const char * stringValue(sxnc_environment environ, jobject value){
530
    jclass  objClass = lookForClass(environ.env, "java/lang/Object");
531
    static jmethodID strMID = NULL;
532
    if(!strMID) {
533
        strMID = (jmethodID)(*(environ.env))->GetMethodID(environ.env, objClass, "toString", "()Ljava/lang/String;");
534
        if(!strMID) {
535
            printf("\nError: Object %s() not found\n","toString");
536
            fflush (stdout);
537
                          return NULL;
538
        }
539
    }
540
    jstring result = (jstring)((*(environ.env))->CallObjectMethod(environ.env, value, strMID));
541
    if(result) {
542
        const char * str = (*(environ.env))->GetStringUTFChars(environ.env, result, NULL);    
543
        return str;
544
    }
545
    
546
    //checkForException(environ, cppClass, cpp);
547
    return 0;
548
    
549
}
550

    
551

    
552

    
553

    
(1-1/3)