Project

Profile

Help

Feature #2422 ยป Transform.c

O'Neil Delpratt, 2015-07-29 19:15

 
1
#include <jni.h>
2

    
3
#ifdef __linux__
4
    #include <stdlib.h>
5
    #include <string.h>
6
    #include <dlfcn.h>
7
    #include <stdio.h>  
8
    #define HANDLE void*
9
    #define LoadLibrary(x) dlopen(x, RTLD_LAZY)
10
//    #define FreeLibrary(x) dlclose(x, RTLD_LAZY)
11
    #define GetProcAddress(x,y) dlsym(x,y)
12
#else
13
    #include <windows.h>
14
#endif
15

    
16
typedef int bool;
17
#define true 1
18
#define false 0
19

    
20

    
21
char dllname[] =
22
    #ifdef __linux__
23
        "/usr/lib/libsaxon.so";
24
    #else
25
        "Saxon-hec.dll";
26
    #endif
27

    
28
//===============================================================================================//
29
/*! <code>Environment</code>. This struct captures the jni, JVM and handler to the cross compiled Saxon/C library.
30
 * <p/>
31
 */
32
typedef struct {
33
                JNIEnv *env;
34
                HANDLE myDllHandle;
35
                JavaVM *jvm;
36
        } Environment;
37

    
38

    
39
//===============================================================================================//
40

    
41
/*! <code>MyParameter</code>. This struct captures details of paramaters used for the transformation as (string, value) pairs.
42
 * <p/>
43
 */
44
typedef struct {
45
                char* name;
46
                jobject value;
47
        } MyParameter;
48

    
49
//===============================================================================================//
50

    
51
/*! <code>MyProperty</code>. This struct captures details of properties used for the transformation as (string, string) pairs.
52
 * <p/>
53
 */
54
typedef struct {
55
                char * name;
56
                char * value;
57
        } MyProperty;
58

    
59
jobject cpp;
60

    
61

    
62

    
63
const char * failure;
64
/*
65
 * Load dll.
66
 */
67
HANDLE loadDll(char* name)
68
{
69
    HANDLE hDll = LoadLibrary (name);
70

    
71
    if (!hDll) {
72
        printf ("Unable to load %s\n", name);
73
        exit(1);
74
    }
75
#ifdef DEBUG
76
    printf ("%s loaded\n", name);
77
#endif
78
    return hDll;
79
}
80

    
81

    
82
jint (JNICALL * JNI_GetDefaultJavaVMInitArgs_func) (void *args);
83
jint (JNICALL * JNI_CreateJavaVM_func) (JavaVM **pvm, void **penv, void *args);
84

    
85
/*
86
 * Initialize JET run-time.
87
 */
88
void initJavaRT(HANDLE myDllHandle, JavaVM** pjvm, JNIEnv** penv)
89
{
90
    int            result;
91
    JavaVMInitArgs args;
92

    
93
    JNI_GetDefaultJavaVMInitArgs_func = 
94
             (jint (JNICALL *) (void *args))
95
             GetProcAddress (myDllHandle, "JNI_GetDefaultJavaVMInitArgs");
96

    
97
    JNI_CreateJavaVM_func =
98
             (jint (JNICALL *) (JavaVM **pvm, void **penv, void *args))
99
             GetProcAddress (myDllHandle, "JNI_CreateJavaVM");
100

    
101
    if(!JNI_GetDefaultJavaVMInitArgs_func) {
102
        printf ("%s doesn't contain public JNI_GetDefaultJavaVMInitArgs\n", dllname);
103
        exit (1);
104
    }
105

    
106
    if(!JNI_CreateJavaVM_func) {
107
        printf ("%s doesn't contain public JNI_CreateJavaVM\n", dllname);
108
        exit (1);
109
    }
110

    
111
    memset (&args, 0, sizeof(args));
112

    
113
    args.version = JNI_VERSION_1_2;
114
    result = JNI_GetDefaultJavaVMInitArgs_func(&args);
115
    if (result != JNI_OK) {
116
        printf ("JNI_GetDefaultJavaVMInitArgs() failed with result %d\n", result);
117
        exit(1);
118
    }
119
  
120
    /*
121
     * NOTE: no JVM is actually created
122
     * this call to JNI_CreateJavaVM is intended for JET RT initialization
123
     */
124
    result = JNI_CreateJavaVM_func (pjvm, (void **)penv, &args);
125
    if (result != JNI_OK) {
126
        printf ("JNI_CreateJavaVM() failed with result %d\n", result);
127
        exit(1);
128
    }
129
#ifdef DEBUG
130
    printf ("JET RT initialized\n");
131
    fflush (stdout);
132
#endif
133
}
134

    
135

    
136
/*
137
 * Look for class.
138
 */
139
jclass lookForClass (JNIEnv* penv, char* name)
140
{
141
    jclass clazz = (*penv)->FindClass (penv, name);
142

    
143
    if (!clazz) {
144
        printf("Unable to find class %s\n", name);
145
        return NULL;
146
    }
147
#ifdef DEBUG
148
    printf ("Class %s found\n", name);
149
    fflush (stdout);
150
#endif
151

    
152
    return clazz;
153
}
154

    
155

    
156
/*
157
 * Create an object and invoke the "ifoo" instance method
158
 */
159
void invokeInstanceMethod (JNIEnv* penv, jclass myClassInDll)
160
{
161
    jmethodID MID_init, MID_ifoo;
162
    jobject obj;
163

    
164
    MID_init = (*penv)->GetMethodID (penv, myClassInDll, "<init>", "()V");
165
    if (!MID_init) {
166
        printf("Error: MyClassInDll.<init>() not found\n");
167
        return;
168
    }
169

    
170
    obj = (*penv)->NewObject(penv, myClassInDll, MID_init);
171
    if (!obj) {
172
        printf("Error: failed to allocate an object\n");
173
        return;
174
    }
175

    
176
    MID_ifoo = (*penv)->GetMethodID (penv, myClassInDll, "ifoo", "()V");
177

    
178
    if (!MID_ifoo) {
179
        printf("Error: MyClassInDll.ifoo() not found\n");
180
        return;
181
    }
182
    
183
    (*(penv))->CallVoidMethod (penv, obj, MID_ifoo);
184
}
185

    
186

    
187

    
188
/*
189
 * Invoke the "foo" static method
190
 */
191
void invokeStaticMethod(JNIEnv* penv, jclass myClassInDll)
192
{
193
    jmethodID MID_foo;
194

    
195
    MID_foo = (*penv)->GetStaticMethodID(penv, myClassInDll, "foo", "()V");
196
    if (!MID_foo) {
197
        printf("\nError: MyClassInDll.foo() not found\n");
198
        return;
199
    }
200
    
201
    (*penv)->CallStaticVoidMethod(penv, myClassInDll, MID_foo);
202
}
203

    
204
jmethodID findConstructor (JNIEnv* penv, jclass myClassInDll, char* arguments)
205
{
206
    jmethodID MID_init, mID;
207
    jobject obj;
208

    
209
    MID_init = (jmethodID)(*penv)->GetMethodID (penv, myClassInDll, "<init>", arguments);
210
    if (!MID_init) {
211
        printf("Error: MyClassInDll.<init>() not found\n");
212
        fflush (stdout);
213
        return 0;
214
    }
215

    
216
  return MID_init;
217
}
218

    
219
jobject createObject (JNIEnv* penv, jclass myClassInDll, const char * arguments)
220
{
221
    jmethodID MID_init, mID;
222
    jobject obj;
223

    
224
    MID_init = (jmethodID)(*(penv))->GetMethodID (penv, myClassInDll, "<init>", arguments);
225
    if (!MID_init) {
226
        printf("Error: MyClassInDll.<init>() not found\n");
227
        return NULL;
228
    }
229

    
230
      obj = (jobject)(*(penv))->NewObject(penv, myClassInDll, MID_init, (jboolean)true);
231
      if (!obj) {
232
        printf("Error: failed to allocate an object\n");
233
        return NULL;
234
      }
235
    return obj;
236
}
237

    
238
void checkForException(Environment environ, jclass callingClass,  jobject callingObject){
239

    
240
    if ((*(environ.env))->ExceptionCheck(environ.env)) {
241
        char *  result1;
242
        const char * errorCode = NULL;
243
        jthrowable exc = (*(environ.env))->ExceptionOccurred(environ.env);
244
        (*(environ.env))->ExceptionDescribe(environ.env); //comment code
245
         jclass exccls = (jclass)(*(environ.env))->GetObjectClass(environ.env, exc);
246
        jclass clscls = (jclass)(*(environ.env))->FindClass(environ.env, "java/lang/Class");
247

    
248
        jmethodID getName = (jmethodID)(*(environ.env))->GetMethodID(environ.env, clscls, "getName", "()Ljava/lang/String;");
249
        jstring name =(jstring)((*(environ.env))->CallObjectMethod(environ.env, exccls, getName));
250
        char const* utfName = (char const*)(*(environ.env))->GetStringUTFChars(environ.env, name, 0);
251
        printf(utfName);
252

    
253
         jmethodID  getMessage = (jmethodID)(*(environ.env))->GetMethodID(environ.env, exccls, "getMessage", "()Ljava/lang/String;");
254
        if(getMessage) {
255

    
256
                jstring message = (jstring)((*(environ.env))->CallObjectMethod(environ.env, exc, getMessage));
257
                if(message) {                
258
                        char const* utfMessage = (char const*)(*(environ.env))->GetStringUTFChars(environ.env, message, 0);
259
                }
260
        
261
        }
262

    
263
     }
264
        //return NULL;
265

    
266
}
267

    
268

    
269
void finalizeJavaRT (JavaVM* jvm)
270
{
271
    (*jvm)->DestroyJavaVM (jvm);
272
}
273

    
274

    
275

    
276

    
277

    
278
int transform(Environment environ, int argc, const char* argv[]) {
279

    
280

    
281
    jmethodID MID_foo;
282
    jclass transClass = lookForClass(environ.env, "net/sf/saxon/Transform");
283
    char methodName[] = "main";
284
    char args[] = "([Ljava/lang/String;)V";
285
    jobjectArray stringArray = NULL;
286
    MID_foo = (jmethodID)(*(environ.env))->GetStaticMethodID(environ.env, transClass, methodName, args);
287
    if (!MID_foo) {
288
        printf("\nError: MyClassInDll %s() not found\n",methodName);
289
        fflush (stdout);
290
        return -1;
291
    }
292
     if(argc < 2) {
293
        printf("\nError: Not enough arguments in Transform");
294
        return 0;
295
    }
296
           jclass stringClass = lookForClass(environ.env, "java/lang/String");
297
           stringArray = (*(environ.env))->NewObjectArray(environ.env, (jint)argc-1, stringClass, 0 );
298
           if(!stringArray) { return 0;}
299
  int i, j;
300
  for(i=1, j=0; i< argc; i++, j++) {
301
             (*(environ.env))->SetObjectArrayElement(environ.env, stringArray, j, (*(environ.env))->NewStringUTF(environ.env, argv[i]));
302
           }
303

    
304
   (*(environ.env))->CallStaticVoidMethod(environ.env, transClass, MID_foo, stringArray);
305
   
306
  (*(environ.env))->DeleteLocalRef(environ.env, stringArray);
307
        return 0;
308
}
309

    
310

    
311

    
312

    
313
int main( int argc, const char* argv[] )
314
{
315
    HANDLE myDllHandle;
316
    //JNIEnv *(environ.env);
317
    //JavaVM *jvm;
318
    jclass  myClassInDll;
319

    
320
    Environment environ;
321
    /*
322
     * First of all, load required component.
323
     * By the time of JET initialization, all components should be loaded.
324
     */
325
    environ.myDllHandle = loadDll (dllname);
326
   
327

    
328
    /*
329
     * Initialize JET run-time.
330
     * The handle of loaded component is used to retrieve Invocation API.
331
     */
332
    initJavaRT (environ.myDllHandle, &environ.jvm, &environ.env);
333
    transform(environ, argc, argv);        
334

    
335
  
336
fflush(stdout);
337
    /*
338
     * Finalize JET run-time.
339
     */
340
    finalizeJavaRT (environ.jvm);
341

    
342
    return 0;
343
}
    (1-1/1)