Project

Profile

Help

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

he / latest9.6 / hec / Saxon.C.API / PEC / SaxonCGlue.c @ f62330e8

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
                env_len = 8;
31
                dllname =malloc(sizeof(char)*name_len+env_len+1);
32
                resources_dir =malloc(sizeof(char)*rDir_len+env_len+1);
33
#ifdef DEBUG
34
                if(dllname == NULL || resources_dir == NULL)
35
                {
36
                      // error
37
                  printf("Error in allocation of Dllname\n");
38
                }
39
#endif
40
                memset(&dllname[0], 0, sizeof(dllname));
41
                memset(&resources_dir[0], 0, sizeof(resources_dir));
42
#ifdef __linux__
43
                
44
                       snprintf(dllname, 8+name_len+1, "%s%s", "/usr/lib", tempDllname);
45
                snprintf(resources_dir, 8+rDir_len+1, "%s%s", "/usr/lib", tempResources_dir);
46
#elif  defined (__APPLE__) && defined(__MACH__)
47
                       snprintf(dllname, 8+name_len+1, "%s%s", "/usr/lib", tempDllname);
48
                snprintf(resources_dir, 8+rDir_len+1, "%s%s", "/usr/lib", tempResources_dir);
49
#else
50
                //TODO When windows version of Saxon/C is done we will have to fixup this
51
                strncpy(dllname, "C:\\Program Files\\Saxonica\\SaxonPEC1.0.1", 42);
52
                strncpy(resources_dir, "C:\\Program Files\\Saxonica\\SaxonPEC1.0.1", 42);
53
#endif
54

    
55
        
56

    
57
        }
58
                
59

    
60
#ifdef DEBUG        
61

    
62
                printf("Library length: %i\n", name_len);
63
                printf("Env length: %i\n", env_len);
64
                printf("dllname length alloc: %i\n", (env_len+name_len+1));
65
                printf("resources length alloc: %i\n", (env_len+rDir_len+1));                
66
                printf("size of dllname %i\n", strlen(dllname));
67
                printf("dllName: %s\n", dllname);
68
                printf("resources_dir: %s\n", resources_dir);
69
                printf("size of resources dir %i\n", strlen(resources_dir));
70
#endif         
71

    
72
}
73

    
74
char * getDllname(){
75
        return dllname;
76
}
77

    
78
char * getResourceDirectory(){
79
        return resources_dir;
80
}
81

    
82
/*
83
 * Load dll using the default setting in Saxon/C
84
 * Recommended method to use to load library
85
 */
86
HANDLE loadDefaultDll(){
87
        return loadDll(NULL);
88
}
89

    
90

    
91
/*
92
 * Load dll.
93
 */
94
HANDLE loadDll(char* name)
95
{
96
        if(name == NULL) {
97
                setDllname();
98
                name = getDllname();
99
                //perror("Error1: ");
100
        }
101

    
102
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
103
    HANDLE hDll = LoadLibrary (_T(name)); // Used for windows only
104
#else
105
    HANDLE hDll = LoadLibrary(name);
106
#endif
107

    
108
    if (!hDll) {
109
        fprintf (stderr, "Unable to load %s\n", name);
110
        perror("Error: ");
111
        exit(1);
112
    }
113
#ifdef DEBUG
114
    fprintf (stderr, "%s loaded\n", name);
115
#endif
116

    
117
    return hDll;
118
}
119

    
120

    
121

    
122
jint (JNICALL * JNI_GetDefaultJavaVMInitArgs_func) (void *args);
123
jint (JNICALL * JNI_CreateJavaVM_func) (JavaVM **pvm, void **penv, void *args);
124

    
125

    
126

    
127
void initDefaultJavaRT(sxnc_environment ** env){
128
        sxnc_environment *environ = *env;
129
        initJavaRT((environ->myDllHandle), &(environ->jvm), &(environ->env));
130
}
131

    
132
/*
133
 * Initialize JET run-time.
134
 */
135
void initJavaRT(HANDLE myDllHandle, JavaVM** pjvm, JNIEnv** penv)
136
{
137
if(jvmCreated==0) {
138
     jvmCreated=1;
139
#ifdef DEBUG
140
    perror ("initJavaRT - load Saxon/C library\n");
141
#endif
142
    int result;
143
    JavaVMInitArgs args;
144
    JNI_GetDefaultJavaVMInitArgs_func =
145
    (jint (JNICALL *) (void *args))
146
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
147
    GetProcAddress ((HMODULE)myDllHandle, "JNI_GetDefaultJavaVMInitArgs");
148
#else
149
    GetProcAddress (myDllHandle, "JNI_GetDefaultJavaVMInitArgs");
150
#endif
151
 
152
    
153
    JNI_CreateJavaVM_func =
154
    (jint (JNICALL *) (JavaVM **pvm, void **penv, void *args))
155
    
156
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
157
    GetProcAddress ((HMODULE)myDllHandle, "JNI_CreateJavaVM");
158
#else
159
    GetProcAddress (myDllHandle, "JNI_CreateJavaVM");
160
    
161
#endif
162

    
163
    
164
    if(!JNI_GetDefaultJavaVMInitArgs_func) {
165
        fprintf (stderr,"%s doesn't contain public JNI_GetDefaultJavaVMInitArgs\n", getDllname());
166
        exit (1);
167
    }
168
    
169
    if(!JNI_CreateJavaVM_func) {
170
        fprintf (stderr,"%s doesn't contain public JNI_CreateJavaVM\n", getDllname());
171
        exit (1);
172
    }
173
    
174
    memset (&args, 0, sizeof(args));
175
    
176
    args.version = JNI_VERSION_1_2;
177
    result = JNI_GetDefaultJavaVMInitArgs_func(&args);
178
    if (result != JNI_OK) {
179
        fprintf(stderr,"JNI_GetDefaultJavaVMInitArgs() failed with result\n");
180
        exit(1);
181
    }
182
  
183
    /*
184
     * NOTE: no JVM is actually created
185
     * this call to JNI_CreateJavaVM is intended for JET RT initialization
186
     */
187
    result = JNI_CreateJavaVM_func (pjvm, (void **)penv, &args);
188
    if (result != JNI_OK) {
189
        fprintf(stderr,"JNI_CreateJavaVM() failed with result: %i\n",result);
190
        exit(1);
191
    }
192

    
193

    
194
    fflush (stdout);
195
  } else {
196
#ifdef DEBUG
197
    perror ("initJavaRT - Saxon/C library loaded already\n");
198
#endif
199
        }
200
}
201

    
202

    
203
/*
204
 * Look for class.
205
 */
206
jclass lookForClass (JNIEnv* penv, const char* name)
207
{
208
    jclass clazz = (*penv)->FindClass (penv, name);
209

    
210
    if (!clazz) {
211
        printf("Unable to find class %s\n", name);
212
        return NULL;
213
    }
214
#ifdef DEBUG
215
    printf ("Class %s found\n", name);
216
    fflush (stdout);
217
#endif
218

    
219
    return clazz;
220
}
221

    
222

    
223
/*
224
 * Create an object and invoke the instance method
225
 */
226
void invokeInstanceMethod (JNIEnv* penv, jclass myClassInDll, char * name, char * arguments)
227
{
228
    jmethodID MID_init, MID_name;
229
    jobject obj;
230

    
231
    MID_init = (*penv)->GetMethodID (penv, myClassInDll, "<init>", "()V");
232
    if (!MID_init) {
233
        printf("Error: MyClassInDll.<init>() not found\n");
234
        return;
235
    }
236

    
237
    obj = (*penv)->NewObject(penv, myClassInDll, MID_init);
238
    if (!obj) {
239
        printf("Error: failed to allocate an object\n");
240
        return;
241
    }
242

    
243
    MID_name = (*penv)->GetMethodID (penv, myClassInDll, name, arguments);
244

    
245
    if (!MID_name) {
246
        printf("Error: %s not found\n", name);
247
        return;
248
    }
249
    
250
    (*(penv))->CallVoidMethod (penv, obj, MID_name);
251
}
252

    
253

    
254

    
255

    
256
/*
257
 * Invoke the static method
258
 */
259
void invokeStaticMethod(JNIEnv* penv, jclass myClassInDll, char* name, char* arguments)
260
{
261
    jmethodID MID_name;
262

    
263
    MID_name = (*penv)->GetStaticMethodID(penv, myClassInDll, name, arguments);
264
    if (!MID_name) {
265
        printf("\nError: method %s not found\n", name);
266
        return;
267
    }
268
    
269
    (*penv)->CallStaticVoidMethod(penv, myClassInDll, MID_name);
270
}
271

    
272

    
273
/*
274
 * Find a constructor with a set arguments
275
 */
276
jmethodID findConstructor (JNIEnv* penv, jclass myClassInDll, char* arguments)
277
{
278
    jmethodID MID_initj;
279
    jobject obj;
280

    
281
    MID_initj = (jmethodID)(*penv)->GetMethodID (penv, myClassInDll, "<init>", arguments);
282
    if (!MID_initj) {
283
        printf("Error: MyClassInDll.<init>() not found\n");
284
        fflush (stdout);
285
        return 0;
286
    }
287

    
288
  return MID_initj;
289
}
290

    
291
/*
292
 * Create the Java SaxonProcessor
293
 */
294
jobject createSaxonProcessor (JNIEnv* penv, jclass myClassInDll, const char * arguments, jobject argument1, jboolean license)
295
{
296
    jmethodID MID_initi;
297

    
298
    jobject obj;
299

    
300
    MID_initi = (jmethodID)(*(penv))->GetMethodID (penv, myClassInDll, "<init>", arguments);
301
        if (!MID_initi) {
302
                printf("Error: MyClassInDll.<init>() not found\n");
303
                return NULL;
304
        }
305
     
306
    if(argument1) {
307

    
308
             obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi, argument1, license);
309
    } else {
310
        
311
      obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi, license);
312
     }
313
      if (!obj) {
314
        printf("Error: failed to allocate an object\n");
315
        return NULL;
316
      }
317
    return obj;
318
}
319

    
320

    
321
/*
322
 * Create the Java SaxonProcessor without boolean license argument
323
 */
324
jobject createSaxonProcessor2 (JNIEnv* penv, jclass myClassInDll, const char * arguments, jobject argument1)
325
{
326
    jmethodID MID_initi;
327

    
328
    jobject obj;
329

    
330
    MID_initi = (jmethodID)(*(penv))->GetMethodID (penv, myClassInDll, "<init>", arguments);
331
        if (!MID_initi) {
332
                printf("Error: MyClassInDll.<init>() not found\n");
333
                return NULL;
334
        }
335
     
336
    if(argument1) {
337

    
338
             obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi, argument1);
339
    } else {
340
        
341
      obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi);
342
     }
343
      if (!obj) {
344
        printf("Error: failed to allocate an object\n");
345
        return NULL;
346
      }
347
    return obj;
348
}
349

    
350

    
351
/*
352
 * Callback to check for exceptions. When called it returns the exception as a string 
353
 */
354
const char * checkForException(sxnc_environment environ, jclass callingClass,  jobject callingObject){
355

    
356
    if ((*(environ.env))->ExceptionCheck(environ.env)) {
357

    
358
        jthrowable exc = (*(environ.env))->ExceptionOccurred(environ.env);
359
#ifdef DEBUG
360
        (*(environ.env))->ExceptionDescribe(environ.env);
361
#endif
362
         if(exc) {
363
                printf("Exception Occurred!");
364
        }
365
        jclass exccls = (jclass) (*(environ.env))->GetObjectClass(environ.env, exc);
366

    
367
        jclass clscls = (jclass) (*(environ.env))->FindClass(environ.env, "java/lang/Class");
368
        
369
        jmethodID getName = (jmethodID)(*(environ.env))->GetMethodID(environ.env, clscls, "getName", "()Ljava/lang/String;");
370
        jstring name = (jstring)((*(environ.env))->CallObjectMethod(environ.env, exccls, getName));
371
        char const* utfName = (*(environ.env))->GetStringUTFChars(environ.env, name, NULL);
372
        
373
        if(callingObject != NULL && strcmp(utfName, "net.sf.saxon.s9api.SaxonApiException") == 0){
374
                  
375
                jclass saxonExcClass = (*(environ.env))->FindClass(environ.env, "java/lang/Throwable");
376
                
377
                jmethodID  getMessage =  (jmethodID)(*(environ.env))->GetMethodID(environ.env, exccls, "getMessage", "()Ljava/lang/String;");
378
                
379
        if(getMessage) {
380
            
381
            jstring message = (jstring)((*(environ.env))->CallObjectMethod(environ.env, exc, getMessage));
382
       
383
        if(!message){
384
        
385
        (*(environ.env))->ExceptionClear(environ.env);
386
        return 0;
387
        }
388
            char const* utfMessage= (*(environ.env))->GetStringUTFChars(environ.env, message, NULL);
389
      
390
            if(utfMessage != NULL) {
391
                (*(environ.env))->ReleaseStringUTFChars(environ.env, name, utfName);
392
            }
393
       
394
            (*(environ.env))->ExceptionClear(environ.env);
395
            return utfMessage;
396
        }
397
    }
398
     (*(environ.env))->ReleaseStringUTFChars(environ.env, name, utfName);      
399
    }
400
(*(environ.env))->ExceptionClear(environ.env);
401
    return NULL;
402
}
403

    
404

    
405
/*
406
 * Clean up and destroy Java VM to release memory used. 
407
 */
408
void finalizeJavaRT (JavaVM* jvm)
409
{
410

    
411
  if(jvmCreated!= 0){
412
    (*jvm)->DestroyJavaVM (jvm);
413
    jvmCreated=0;        
414
  }
415
}
416

    
417

    
418
/*
419
 * Get a parameter from list 
420
 */
421
jobject getParameter(sxnc_parameter *parameters,  int parLen, const char* namespacei, const char * name){
422
        int i =0;
423
        for(i =0; i< parLen;i++) {
424
                if(strcmp(parameters[i].name, name) == 0)
425
                        return (jobject)parameters[i].value;                        
426
        }
427
        return NULL;
428
}
429

    
430

    
431
/*
432
 * Get a property from list 
433
 */
434
char* getProperty(sxnc_property * properties, int propLen, const char* namespacei, const char * name){
435
        int i =0;
436
        for(i =0; i< propLen;i++) {
437
                if(strcmp(properties[i].name, name) == 0)
438
                        return properties[i].value;                        
439
        }
440
        return 0;
441
}
442

    
443

    
444
/*
445
 * set a parameter 
446
 */
447
void setParameter(sxnc_parameter **parameters, int * parLen, int * parCap, const char * namespacei, const char * name, jobject value){
448

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

    
470

    
471
/*
472
 * set a property 
473
 */
474
void setProperty(sxnc_property ** properties, int *propLen, int *propCap, const char* name, const char* value){        
475
        if(getProperty(*properties, (*propLen), "", name) != 0){
476
                return;                        
477
        }
478
                
479
        if(((*propLen)+1) >= (*propCap)) {
480
                (*propCap) *=2; 
481
                sxnc_property* temp = (sxnc_property*)malloc(sizeof(sxnc_property)*  (*propCap));
482
                int i =0;        
483
                for(i =0; i< (*propLen)-1;i++) {
484
                        temp[i] = (*properties)[i];                        
485
                }
486
                free(properties);
487
                properties = &temp;
488

    
489
        }
490
        int nameLen = strlen(name)+1;        
491
        char *newName = (char*)malloc(sizeof(char)*nameLen);
492
          snprintf(newName, nameLen, "%s", name );
493
        char *newValue = (char*)malloc(sizeof(char)*strlen(value)+1);
494
          snprintf(newValue, strlen(value)+1, "%s", value );
495
        (*properties)[(*propLen)].name = (char*)newName;        
496
        (*properties)[(*propLen)].value = (char*)newValue;
497
        (*propLen)++;
498
}
499

    
500
/*
501
 * clear parameter 
502
 */
503
void clearSettings(sxnc_parameter **parameters, int *parLen, sxnc_property ** properties, int *propLen){
504
        int i =0;
505
        free(*parameters);
506
        free(*parameters);
507
        /*for(i =0; i< parLen; i++){
508
                free((*parameters[i].name);
509
                free(parameters[i].value);
510
        }
511
        for(i =0; i< propLen; i++){
512
                free(properties[i].name);
513
                free(properties[i].value);
514
        }*/
515

    
516
            *parameters = (sxnc_parameter *)calloc(10, sizeof(sxnc_parameter));
517
            *properties = (sxnc_property *)calloc(10, sizeof(sxnc_property));
518
        (*parLen) = 0;
519
        (*propLen) = 0;
520
}
521

    
522

    
523
const char * stringValue(sxnc_environment environ, jobject value){
524
        jclass  objClass = lookForClass(environ.env, "java/lang/Object");
525
        static jmethodID strMID = NULL;
526
        if(!strMID) {
527
                strMID = (jmethodID)(*(environ.env))->GetMethodID(environ.env, objClass, "toString", "()Ljava/lang/String;");
528
                if(!strMID) {
529
                          printf("\nError: Object %s() not found\n","toString");
530
                            fflush (stdout);
531
                          return NULL;
532
                }
533
        }
534
        jstring result = (jstring)((*(environ.env))->CallObjectMethod(environ.env, value, strMID));
535
         if(result) {
536
                       const char * str = (*(environ.env))->GetStringUTFChars(environ.env, result, NULL);    
537
                return str;
538
        }
539

    
540
    //checkForException(environ, cppClass, cpp);
541
    return 0;
542
        
543
}
544

    
545

    
546

    
547

    
(1-1/3)