Project

Profile

Help

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

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

1
#include "SaxonCGlue.h"
2

    
3
jobject cpp;
4
char * dllname;
5
char * resources_dir;
6
int jvmCreated = 0;
7
static char tempDllname[] =
8
#if defined (__linux__)
9
        "/libsaxonpec.so";
10
    #elif  defined (__APPLE__) && defined(__MACH__)
11
        "/libsaxonpec.dylib";
12
    #else
13
         "\\libsaxonpec.dll";
14
    #endif
15

    
16
static char tempResources_dir[] =
17
     #ifdef __linux__
18
        "/saxon-data";
19
    #elif  defined (__APPLE__) && defined(__MACH__)
20
        "/saxon-data";
21
    #else
22
         "\\saxon-data";
23
    #endif
24

    
25
/*
26
* Set Dll name. Also set the saxon resources directory.
27
* If the SAXONC_HOME sxnc_environmental variable is set then use that as base.
28
*/
29
void setDllname(){
30
        size_t name_len  = strlen(tempDllname);
31
        size_t rDir_len  = strlen(tempResources_dir);
32
        char * env = getenv("SAXONC_HOME");
33
        size_t env_len;
34
        if(env!= NULL) {
35

    
36

    
37
                env_len = strlen(env);
38
                dllname =malloc(sizeof(char)*name_len+env_len+1);
39
                resources_dir =malloc(sizeof(char)*rDir_len+env_len+1);
40
                snprintf(dllname, env_len+name_len+1, "%s%s", env, tempDllname);
41
                snprintf(resources_dir, env_len+rDir_len+1, "%s%s", env, tempResources_dir);
42

    
43
#ifdef DEBUG
44

    
45
                printf("envDir: %s\n", env);
46

    
47

    
48
#endif
49

    
50
       } else {
51
#ifdef __linux__
52
           env_len = 8;
53
#elif  defined (__APPLE__) && defined(__MACH__)
54
           env_len = 14;
55
#else
56
           env_len = 8; //not used under windows
57
#endif
58
                dllname =malloc(sizeof(char)*name_len+42+1);
59
                resources_dir =malloc(sizeof(char)*rDir_len+env_len+1);
60
#ifdef DEBUG
61
                if(dllname == NULL || resources_dir == NULL)
62
                {
63
                      // error
64
                  printf("Error in allocation of Dllname\n");
65
                }
66
#endif
67
                //memset(&dllname[0], 0, sizeof(dllname));
68
                //memset(&resources_dir[0], 0, sizeof(resources_dir));
69
#ifdef __linux__
70

    
71
                       snprintf(dllname, 8+name_len+1, "%s%s", "/usr/lib", tempDllname);
72
                snprintf(resources_dir, 8+rDir_len+1, "%s%s", "/usr/lib", tempResources_dir);
73
#elif  defined (__APPLE__) && defined(__MACH__)
74
                       snprintf(dllname, 14+name_len+1, "%s%s", "/usr/local/lib", tempDllname);
75
                snprintf(resources_dir, 14+rDir_len+1, "%s%s", "/usr/local/lib", tempResources_dir);
76
#else
77
                //TODO When windows version of Saxon/C is done we will have to fixup this
78
                //strncpy_s(dllname, name_len +42 + 1, "C:\\Program Files\\Saxonica\\SaxonEEC1.1.0", 42);
79
                snprintf(resources_dir, rDir_len + 42 + 1,  "C:\\Program Files\\Saxonica\\SaxonPEC1.1.3", tempResources_dir);
80
                snprintf(dllname, name_len+42+1, "%s%s", "C:\\Program Files\\Saxonica\\SaxonPEC1.1.3", tempDllname);
81
#endif
82

    
83

    
84

    
85
        }
86

    
87

    
88
#ifdef DEBUG
89

    
90
                printf("Library length: %i\n", name_len);
91
                printf("Env length: %i\n", env_len);
92
                printf("dllname length alloc: %i\n", (env_len+name_len+1));
93
                printf("resources length alloc: %i\n", (env_len+rDir_len+1));
94
                printf("size of dllname %i\n", strlen(dllname));
95
                printf("dllName: %s\n", dllname);
96
                printf("resources_dir: %s\n", resources_dir);
97
                printf("size of resources dir %i\n", strlen(resources_dir));
98
#endif
99

    
100
}
101

    
102
char * getDllname(){
103
        return dllname;
104
}
105

    
106
char * getResourceDirectory(){
107
        return resources_dir;
108
}
109

    
110
char * _getResourceDirectory(){
111
        return resources_dir;
112
}
113

    
114
/*
115
 * Load dll using the default setting in Saxon/C
116
 * Recommended method to use to load library
117
 */
118
HANDLE loadDefaultDll(){
119
        return loadDll(NULL);
120
}
121

    
122

    
123
/*
124
 * Load dll.
125
 */
126
HANDLE loadDll(char* name)
127
{
128
        if(name == NULL) {
129
                setDllname();
130
                name = getDllname();
131
                //perror("Error1: ");
132
        }
133

    
134
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
135
    HANDLE hDll = LoadLibrary (name); // Used for windows only
136
#else
137
    HANDLE hDll = LoadLibrary(name);
138
#endif
139
    if (!hDll) {
140
        fprintf (stderr, "Unable to load %s\n", name);
141
                perror("Error: ");
142
        exit(1);
143
    }
144
#ifdef DEBUG
145
    fprintf (stderr, "%s loaded\n", name);
146
#endif
147

    
148
    return hDll;
149
}
150

    
151

    
152

    
153
jint (JNICALL * JNI_GetDefaultJavaVMInitArgs_func) (void *args);
154
jint (JNICALL * JNI_CreateJavaVM_func) (JavaVM **pvm, void **penv, void *args);
155

    
156

    
157

    
158
void initDefaultJavaRT(sxnc_environment *env){
159
        sxnc_environment *environi = env;
160
        initJavaRT((environi->myDllHandle), &(environi->jvm), &(environi->env));
161
}
162

    
163
/*
164
 * Initialize JET run-time.
165
 */
166
void initJavaRT(HANDLE myDllHandle, JavaVM** pjvm, JNIEnv** penv)
167
{
168
if(jvmCreated==0) {
169
     jvmCreated=1;
170
#ifdef DEBUG
171
    perror ("initJavaRT - load Saxon/C library\n");
172
#endif
173
    int result;
174
    JavaVMInitArgs args;
175
    JNI_GetDefaultJavaVMInitArgs_func =
176
    (jint (JNICALL *) (void *args))
177
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
178
    GetProcAddress ((HMODULE)myDllHandle, "JNI_GetDefaultJavaVMInitArgs");
179
#else
180
    GetProcAddress (myDllHandle, "JNI_GetDefaultJavaVMInitArgs");
181
#endif
182

    
183

    
184
    JNI_CreateJavaVM_func =
185
    (jint (JNICALL *) (JavaVM **pvm, void **penv, void *args))
186

    
187
#if !(defined (__linux__) || (defined (__APPLE__) && defined(__MACH__)))
188
    GetProcAddress ((HMODULE)myDllHandle, "JNI_CreateJavaVM");
189
#else
190
    GetProcAddress (myDllHandle, "JNI_CreateJavaVM");
191

    
192
#endif
193

    
194

    
195
    if(!JNI_GetDefaultJavaVMInitArgs_func) {
196
        fprintf (stderr,"%s doesn't contain public JNI_GetDefaultJavaVMInitArgs\n", getDllname());
197
        exit (1);
198
    }
199

    
200
    if(!JNI_CreateJavaVM_func) {
201
        fprintf (stderr,"%s doesn't contain public JNI_CreateJavaVM\n", getDllname());
202
        exit (1);
203
    }
204

    
205
    memset (&args, 0, sizeof(args));
206

    
207
    args.version = JNI_VERSION_1_2;
208
    result = JNI_GetDefaultJavaVMInitArgs_func(&args);
209
    if (result != JNI_OK) {
210
        fprintf(stderr,"JNI_GetDefaultJavaVMInitArgs() failed with result\n");
211
        exit(1);
212
    }
213

    
214
    /*
215
     * NOTE: no JVM is actually created
216
     * this call to JNI_CreateJavaVM is intended for JET RT initialization
217
     */
218
    result = JNI_CreateJavaVM_func (pjvm, (void **)penv, &args);
219
    if (result != JNI_OK) {
220
        fprintf(stderr,"JNI_CreateJavaVM() failed with result: %i\n",result);
221
        exit(1);
222
    }
223

    
224

    
225
    fflush (stdout);
226
  } else {
227
#ifdef DEBUG
228
    perror ("initJavaRT - Saxon/C library loaded already\n");
229
#endif
230
        }
231
}
232

    
233

    
234
/*
235
 * Look for class.
236
 */
237
jclass lookForClass (JNIEnv* penv, const char* name)
238
{
239
    jclass clazz = (*penv)->FindClass (penv, name);
240

    
241
    if (!clazz) {
242
        printf("Unable to find class %s\n", name);
243
        return NULL;
244
    }
245
#ifdef DEBUG
246
    printf ("Class %s found\n", name);
247
    fflush (stdout);
248
#endif
249

    
250
    return clazz;
251
}
252

    
253

    
254
/*
255
 * Create an object and invoke the instance method
256
 */
257
void invokeInstanceMethod (JNIEnv* penv, jclass myClassInDll, char * name, char * arguments)
258
{
259
    jmethodID MID_init, MID_name;
260
    jobject obj;
261

    
262
    MID_init = (*penv)->GetMethodID (penv, myClassInDll, "<init>", "()V");
263
    if (!MID_init) {
264
        printf("Error: MyClassInDll.<init>() not found\n");
265
        return;
266
    }
267

    
268
    obj = (*penv)->NewObject(penv, myClassInDll, MID_init);
269
    if (!obj) {
270
        printf("Error: failed to allocate an object\n");
271
        return;
272
    }
273

    
274
    MID_name = (*penv)->GetMethodID (penv, myClassInDll, name, arguments);
275

    
276
    if (!MID_name) {
277
        printf("Error: %s not found\n", name);
278
        return;
279
    }
280

    
281
    (*(penv))->CallVoidMethod (penv, obj, MID_name);
282
}
283

    
284

    
285

    
286

    
287
/*
288
 * Invoke the static method
289
 */
290
void invokeStaticMethod(JNIEnv* penv, jclass myClassInDll, char* name, char* arguments)
291
{
292
    jmethodID MID_name;
293

    
294
    MID_name = (*penv)->GetStaticMethodID(penv, myClassInDll, name, arguments);
295
    if (!MID_name) {
296
        printf("\nError: method %s not found\n", name);
297
        return;
298
    }
299

    
300
    (*penv)->CallStaticVoidMethod(penv, myClassInDll, MID_name);
301
}
302

    
303

    
304
/*
305
 * Find a constructor with a set arguments
306
 */
307
jmethodID findConstructor (JNIEnv* penv, jclass myClassInDll, char* arguments)
308
{
309
    jmethodID MID_initj;
310

    
311
    MID_initj = (jmethodID)(*penv)->GetMethodID (penv, myClassInDll, "<init>", arguments);
312
    if (!MID_initj) {
313
        printf("Error: MyClassInDll.<init>() not found\n");
314
        fflush (stdout);
315
        return 0;
316
    }
317

    
318
  return MID_initj;
319
}
320

    
321
/*
322
 * Create the Java SaxonProcessor
323
 */
324
jobject createSaxonProcessor (JNIEnv* penv, jclass myClassInDll, const char * arguments, jobject argument1, jboolean license)
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, license);
339
    } else {
340

    
341
      obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi, license);
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
 * Create the Java SaxonProcessor without boolean license argument
353
 */
354
jobject createSaxonProcessor2 (JNIEnv* penv, jclass myClassInDll, const char * arguments, jobject argument1)
355
{
356
    jmethodID MID_initi;
357

    
358
    jobject obj;
359

    
360
    MID_initi = (jmethodID)(*(penv))->GetMethodID (penv, myClassInDll, "<init>", arguments);
361
        if (!MID_initi) {
362
                printf("Error: MyClassInDll.<init>() not found\n");
363
                return NULL;
364
        }
365

    
366
    if(argument1) {
367

    
368
             obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi, argument1);
369
    } else {
370

    
371
      obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_initi);
372
     }
373
      if (!obj) {
374
        printf("Error: failed to allocate an object\n");
375
        return NULL;
376
      }
377
    return obj;
378
}
379

    
380

    
381

    
382

    
383
/*
384
 * Callback to check for exceptions. When called it returns the exception as a string
385
 */
386
const char * checkForException(sxnc_environment *environii,  jobject callingObject){
387
        if(callingObject){} // TODO: Remove the callingObject variable
388
    if ((*(environii->env))->ExceptionCheck(environii->env)) {
389

    
390
        jthrowable exc = (*(environii->env))->ExceptionOccurred(environii->env);
391
#ifdef DEBUG
392
        (*(environii->env))->ExceptionDescribe(environii->env);
393
#endif
394
         if(exc) {
395
                printf("Exception Occurred!");
396
        }
397
        jclass exccls = (jclass) (*(environii->env))->GetObjectClass(environii->env, exc);
398

    
399
        jclass clscls = (jclass) (*(environii->env))->FindClass(environii->env, "java/lang/Class");
400

    
401
        jmethodID getName = (jmethodID)(*(environii->env))->GetMethodID(environii->env, clscls, "getName", "()Ljava/lang/String;");
402
        jstring name = (jstring)((*(environii->env))->CallObjectMethod(environii->env, exccls, getName));
403
        char const* utfName = (*(environii->env))->GetStringUTFChars(environii->env, name, NULL);
404

    
405
        //if(callingObject != NULL && strcmp(utfName, "net.sf.saxon.s9api.SaxonApiException") == 0){
406

    
407
                jmethodID  getMessage =  (jmethodID)(*(environii->env))->GetMethodID(environii->env, exccls, "getMessage", "()Ljava/lang/String;");
408

    
409
        if(getMessage) {
410

    
411
            jstring message = (jstring)((*(environii->env))->CallObjectMethod(environii->env, exc, getMessage));
412

    
413
        if(!message){
414

    
415
        (*(environii->env))->ExceptionClear(environii->env);
416
        return 0;
417
        }
418
            char const* utfMessage= (*(environii->env))->GetStringUTFChars(environii->env, message, NULL);
419

    
420
            if(utfMessage != NULL) {
421
                (*(environii->env))->ReleaseStringUTFChars(environii->env, name, utfName);
422
            }
423

    
424
            (*(environii->env))->ExceptionClear(environii->env);
425
            return utfMessage;
426
        }
427
   // }
428
     (*(environii->env))->ReleaseStringUTFChars(environii->env, name, utfName);
429
    }
430
    //(*(environii->env))->ExceptionClear(environii->env);
431
     return 0;
432
}
433

    
434

    
435
/*
436
 * Clean up and destroy Java VM to release memory used.
437
 */
438
void finalizeJavaRT (JavaVM* jvm)
439
{
440

    
441
  if(jvmCreated!= 0){
442
    (*jvm)->DestroyJavaVM (jvm);
443
    jvmCreated=0;
444
  }
445
}
446

    
447

    
448
/*
449
 * Get a parameter from list
450
 */
451
jobject getParameter(sxnc_parameter *parameters,  int parLen, const char* namespacei, const char * name){
452
        int i =0;
453
        namespacei = NULL; // variable not used yet
454
        if(namespacei == NULL) {} // avoiding warning. In next release fix this
455
        for(i =0; i< parLen;i++) {
456
                if(strcmp(parameters[i].name, name) == 0)
457
                        return (jobject)parameters[i].value;
458
        }
459
        return NULL;
460
}
461

    
462

    
463
/*
464
 * Get a property from list
465
 */
466
char* getProperty(sxnc_property * properties, int propLen, const char* namespacei, const char * name){
467
        int i =0;
468
        namespacei = NULL; // variable not used yet
469
        if(namespacei == NULL) {} // avoiding warning. In next release fix this
470
        for(i =0; i< propLen;i++) {
471
                if(strcmp(properties[i].name, name) == 0)
472
                        return properties[i].value;
473
        }
474
        return 0;
475
}
476

    
477

    
478
/*
479
 * set a parameter
480
 */
481
void setParameter(sxnc_parameter **parameters, int * parLen, int * parCap, const char * namespacei, const char * name, jobject value){
482

    
483
        namespacei = NULL;
484
        if(getParameter(*parameters, (*parLen), "", name) != 0){
485
                return;
486
        }
487
        (*parLen)++;
488
        if((*parLen) >= (*parCap)) {
489
                (*parCap) *=2;
490
                sxnc_parameter* temp = (sxnc_parameter*)malloc(sizeof(sxnc_parameter)*(*parCap));
491
                int i =0;
492
                for(i =0; i< (*parLen)-1;i++) {
493
                        temp[i] = (*parameters)[i];
494
                }
495
                free(parameters);
496
                parameters = &temp;
497
        }
498
        int nameLen = strlen(name)+7;
499
        char *newName = malloc(sizeof(char)*nameLen);
500
        int namespaceLen = strlen(namespacei);
501
        char *newNamespace = malloc(sizeof(char)*namespaceLen);
502
          snprintf(newName, nameLen, "%s%s", "param:", name );
503
          snprintf(newNamespace, namespaceLen, "%s", name );
504
        (*parameters)[(*parLen)-1].name = (char*)newName;
505
        (*parameters)[(*parLen)-1].namespacei = (char*)newNamespace;
506
        (*parameters)[(*parLen)-1].value = (jobject)value;
507
}
508

    
509

    
510
/*
511
 * set a property
512
 */
513
void setProperty(sxnc_property ** properties, int *propLen, int *propCap, const char* name, const char* value){
514
        if(getProperty(*properties, (*propLen), "", name) != 0){
515
                return;
516
        }
517

    
518
        if(((*propLen)+1) >= (*propCap)) {
519
                (*propCap) *=2;
520
                sxnc_property* temp = (sxnc_property*)malloc(sizeof(sxnc_property)*  (*propCap));
521
                int i =0;
522
                for(i =0; i< (*propLen)-1;i++) {
523
                        temp[i] = (*properties)[i];
524
                }
525
                free(properties);
526
                properties = &temp;
527

    
528
        }
529
        int nameLen = strlen(name)+1;
530
        char *newName = (char*)malloc(sizeof(char)*nameLen);
531
          snprintf(newName, nameLen, "%s", name );
532
        char *newValue = (char*)malloc(sizeof(char)*strlen(value)+1);
533
          snprintf(newValue, strlen(value)+1, "%s", value );
534
        (*properties)[(*propLen)].name = (char*)newName;
535
        (*properties)[(*propLen)].value = (char*)newValue;
536
        (*propLen)++;
537
}
538

    
539
/*
540
 * clear parameter
541
 */
542
void clearSettings(sxnc_parameter **parameters, int *parLen, sxnc_property ** properties, int *propLen){
543
        free(*parameters);
544
        free(*parameters);
545

    
546

    
547
            *parameters = (sxnc_parameter *)calloc(10, sizeof(sxnc_parameter));
548
            *properties = (sxnc_property *)calloc(10, sizeof(sxnc_property));
549
        (*parLen) = 0;
550
        (*propLen) = 0;
551
}
552

    
553

    
554
const char * stringValue(sxnc_environment *environi, jobject value){
555
        jclass  objClass = lookForClass(environi->env, "java/lang/Object");
556
        static jmethodID strMID = NULL;
557
        if(!strMID) {
558
                strMID = (jmethodID)(*(environi->env))->GetMethodID(environi->env, objClass, "toString", "()Ljava/lang/String;");
559
                if(!strMID) {
560
                          printf("\nError: Object %s() not found\n","toString");
561
                            fflush (stdout);
562
                          return NULL;
563
                }
564
        }
565
        jstring result = (jstring)((*(environi->env))->CallObjectMethod(environi->env, value, strMID));
566
         if(result) {
567
                       const char * str = (*(environi->env))->GetStringUTFChars(environi->env, result, NULL);
568
                return str;
569
        }
570

    
571
    //checkForException(environ, cpp);
572
    return 0;
573
        
574
}
575

    
576

    
577

    
578

    
    (1-1/1)