source: trunk/zoo-project/zoo-kernel/service_internal_java.c @ 781

Last change on this file since 781 was 781, checked in by djay, 8 years ago

Fix issue #140

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 24.7 KB
RevLine 
[580]1/*
[1]2 * Author : Gérald FENOY
3 *
[388]4 * Copyright (c) 2009-2013 GeoLabs SARL
[1]5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service_internal_java.h"
[640]26#include "response_print.h"
[1]27
[580]28/**
29 * Load a JAVA class then run the static public method corresponding to the
30 * service by passing the conf, inputs and outputs parameters by reference.
31 *
32 * @param main_conf the conf maps containing the main.cfg settings
33 * @param request the map containing the HTTP request
34 * @param s the service structure
35 * @param real_inputs the maps containing the inputs
36 * @param real_outputs the maps containing the outputs
37 */
[1]38int zoo_java_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
39  maps* m=*main_conf;
40  maps* inputs=*real_inputs;
41  maps* outputs=*real_outputs;
[767]42  map* cwdMap=getMapFromMaps(*main_conf,"lenv","cwd");
43  char *ntmp=NULL;
44  if(cwdMap!=NULL)
45    ntmp=zStrdup(cwdMap->value);
[1]46  map* tmp=getMap(request,"metapath");
[355]47  char *classpath;
48  char *oclasspath;
[1]49  int res=SERVICE_FAILED;
[352]50  char *cclasspath=getenv("CLASSPATH");
[1]51  if(tmp!=NULL){
[355]52    if(cclasspath!=NULL){
53      classpath=(char*) malloc((strlen(ntmp)+strlen(tmp->value)+strlen(cclasspath)+4)*sizeof(char));
54      oclasspath=(char*) malloc((strlen(ntmp)+strlen(tmp->value)+strlen(cclasspath)+22)*sizeof(char));
[364]55#ifndef WIN32
[352]56      sprintf(classpath,"%s/%s/:%s",ntmp,tmp->value,cclasspath);
[364]57#else
58      sprintf(classpath,"%s/%s/;%s",ntmp,tmp->value,cclasspath);
59#endif
[355]60    }
61    else{
62      classpath=(char*) malloc((strlen(ntmp)+strlen(tmp->value)+3)*sizeof(char));
63      oclasspath=(char*) malloc((strlen(ntmp)+strlen(tmp->value)+21)*sizeof(char));
[352]64      sprintf(classpath,"%s/%s/",ntmp,tmp->value);
[355]65    }
[388]66  }else{
67    if(cclasspath!=NULL){
68      classpath=(char*) malloc((strlen(ntmp)+strlen(cclasspath)+3)*sizeof(char));
69      oclasspath=(char*) malloc((strlen(ntmp)+strlen(cclasspath)+21)*sizeof(char));
70#ifndef WIN32
71      sprintf(classpath,"%s/:%s",ntmp,cclasspath);
72#else
73      sprintf(classpath,"%s/;%s",ntmp,cclasspath);
74#endif
75    }
76    else{
77      classpath=(char*) malloc((strlen(ntmp)+2)*sizeof(char));
78      oclasspath=(char*) malloc((strlen(ntmp)+20)*sizeof(char));
79      sprintf(classpath,"%s/",ntmp);
80    }
[1]81  }
[388]82  sprintf(oclasspath,"-Djava.class.path=%s",classpath);
[1]83#ifdef DEBUG
84  fprintf(stderr,"CLASSPATH=%s\n",classpath);
[354]85  fprintf(stderr,"(%s)\n",oclasspath);
[1]86#endif
[767]87#ifndef USE_JDB
88  int njdb=0;
89#else
90  int njdb=2;
91#endif
[765]92#ifndef WIN32
[771]93  int nb=2+njdb;
[765]94#endif
[771]95  int nbs[3]={0,0,0};
96  maps* javaMap=getMaps(*main_conf,"java");
97  if(javaMap!=NULL){
98    nbs[0]+=count(javaMap->content);
[539]99  }
100  int nbc1=0;
[640]101  maps* javaXMap=getMaps(*main_conf,"javax");
[539]102  if(javaXMap!=NULL){
[771]103    nbs[1]+=count(javaXMap->content);
[539]104  }
[771]105  int nbc0=0;
106  maps* javaXXMap=getMaps(*main_conf,"javaxx");
107  if(javaXXMap!=NULL){
108    nbs[2]+=count(javaXXMap->content);
109  }
[364]110#ifdef WIN32
[771]111  const int nb=2+nbs[1]+nbs[2]+nbs[0];
[765]112  JavaVMOption *options=(JavaVMOption*)malloc(nb*sizeof(JavaVMOption));
[364]113#else
[771]114  JavaVMOption options[nb+nbs[1]+nbs[2]+nbs[0]+1];
[364]115#endif
[1]116  JavaVMInitArgs vm_args;
117  JavaVM *jvm;
118  JNIEnv *env;
119  long result;
120  jmethodID pmid;
[364]121  jclass cls;
122#ifdef JAVA7
123  jobject cls_gr;
124#else
125  jclass cls_gr;
126#endif
[539]127  int i,start;
[748]128  options[0].optionString = oclasspath;
[747]129  options[0].extraInfo=NULL;
[767]130  options[1].optionString = "-server";
131  options[1].extraInfo=NULL;
[771]132#ifdef USE_JDB
133  options[2].optionString = "-Xdebug";
[767]134  options[2].extraInfo=NULL;
[771]135  options[3].optionString = "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7896";
[767]136  options[3].extraInfo=NULL;
137#endif
[364]138#ifdef WIN32
[539]139  start=2;
[388]140  options[1].optionString = "-Xmx512m";
[539]141#else
[771]142  start=2+njdb;
[364]143#endif
[771]144  map *cursors[3]={NULL,NULL,NULL};
145  if(javaMap!=NULL)
146    cursors[0]=javaMap->content;
147  if(javaXMap!=NULL)
148    cursors[1]=javaXMap->content;
149  if(javaXXMap!=NULL)
150    cursors[2]=javaXXMap->content;
151  for(i=0;i<nbs[0];i++){
152    char *tmp=parseJVMOption(cursors[0]);
[748]153    options[start+i].optionString = zStrdup(tmp);
[747]154    options[start+i].extraInfo=NULL;
[539]155    free(tmp);
[771]156    cursors[0]=cursors[0]->next;
[539]157  }
[771]158  for(;i<nbs[0]+nbs[1];i++){
159    char *tmp=parseJVMXOption(cursors[1]);
[748]160    options[start+i].optionString = zStrdup(tmp);
[747]161    options[start+i].extraInfo=NULL;
[539]162    free(tmp);
[771]163    cursors[1]=cursors[1]->next;
[539]164  }
[771]165  for(;i<nbs[0]+nbs[2]+nbs[1];i++){
166    char *tmp=parseJVMXXOption(cursors[2]);
167    options[start+i].optionString = zStrdup(tmp);
168    options[start+i].extraInfo=NULL;
169    free(tmp);
170    cursors[2]=cursors[2]->next;
171  }
[1]172
[59]173  JNI_GetDefaultJavaVMInitArgs(&vm_args);
[352]174  vm_args.version = JNI_VERSION_1_6;
[1]175  vm_args.options = options;
[771]176  vm_args.nOptions = start+nbs[0]+nbs[1]+nbs[2];
[364]177  vm_args.ignoreUnrecognized = JNI_TRUE;
[1]178
179  result = JNI_CreateJavaVM(&jvm,(void **)&env, &vm_args);
180  if(result == JNI_ERR ) {
181    fprintf(stderr,"Error invoking the JVM");
182    return -1;
183  }
184#ifdef DEBUG
[364]185  else
[1]186    fprintf(stderr,"JAVA VM Started\n");
187#endif
188
189  tmp=getMap(s->content,"serviceProvider");
[364]190#ifdef JAVA7
[767]191  cls = (*env).FindClass(tmp->value);
[364]192#else
[1]193  cls = (*env)->FindClass(env,tmp->value);
[364]194#endif
[1]195  if( cls == NULL ) {
[388]196    displayStack(env,*main_conf);
[364]197#ifdef JAVA7
198    (*jvm).DestroyJavaVM();
199#else
[1]200    (*jvm)->DestroyJavaVM(jvm);
[364]201#endif
[352]202    return -1;
[1]203  }
204#ifdef DEBUG
205  else{
206    fprintf(stderr,"%s loaded\n",tmp->value);
207  }
208#endif
[767]209#ifdef JAVA7
210  cls_gr = (*env)NewGlobalRef(cls);
211#else
212  cls_gr = (*env)->NewGlobalRef(env, cls);
213#endif
[1]214
215  if (cls != NULL) {
[364]216#ifdef JAVA7
[771]217@    (*env).ExceptionClear();
[364]218    pmid=(*env).GetStaticMethodID(cls, s->name, "(Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashMap;)I");
219#else
[1]220    (*env)->ExceptionClear(env);
221    pmid=(*env)->GetStaticMethodID(env,cls_gr, s->name, "(Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashMap;)I");
[364]222#endif
[1]223    if (pmid!=0){
224#ifdef DEBUG
225      fprintf(stderr,"Function successfully loaded\n");
226#endif
[57]227      jclass scHashMapClass,scHashMap_class;
228      jmethodID scHashMap_constructor;
[364]229#ifdef JAVA7
230      scHashMapClass = (*env).FindClass("java/util/HashMap");
231      scHashMap_class = (jclass)(*env).NewGlobalRef(scHashMapClass);
232      scHashMap_constructor = (*env).GetMethodID(scHashMap_class, "<init>", "()V");
233#else
[57]234      scHashMapClass = (*env)->FindClass(env, "java/util/HashMap");
235      scHashMap_class = (*env)->NewGlobalRef(env, scHashMapClass);
236      scHashMap_constructor = (*env)->GetMethodID(env, scHashMap_class, "<init>", "()V");
[364]237#endif
[1]238      /**
239       * The 3 standard parameter for each services
240       */
[57]241      jobject arg1=HashMap_FromMaps(env,m,scHashMapClass,scHashMap_class,scHashMap_constructor);
242      jobject arg2=HashMap_FromMaps(env,inputs,scHashMapClass,scHashMap_class,scHashMap_constructor);
243      jobject arg3=HashMap_FromMaps(env,outputs,scHashMapClass,scHashMap_class,scHashMap_constructor);
[1]244      jint pValue=0;
245
[364]246#ifdef JAVA7
247      pValue=(*env).CallStaticIntMethod(cls,pmid,arg1,arg2,arg3);
248#else
[1]249      pValue=(*env)->CallStaticIntMethod(env,cls,pmid,arg1,arg2,arg3);
[364]250#endif
[114]251      if (pValue != (jint)NULL){
[1]252        res=pValue;
[57]253        m=mapsFromHashMap(env,arg1,scHashMapClass);
254        *main_conf=m;
255        outputs=mapsFromHashMap(env,arg3,scHashMapClass);
[1]256        *real_outputs=outputs;
257
258#ifdef DEBUG
259        fprintf(stderr,"Result of call: %i\n", pValue);
260        dumpMaps(inputs);
261        dumpMaps(outputs);
262#endif
[388]263      }else{
264        displayStack(env,*main_conf);
[364]265#ifdef JAVA7
266        (*jvm).DestroyJavaVM();
267#else
[1]268        (*jvm)->DestroyJavaVM(jvm);
[364]269#endif
[9]270        return -1;
[1]271      }
272    }
273    else{
[388]274      displayStack(env,*main_conf);
[364]275#ifdef JAVA7
[767]276      (*env).ExceptionDescribe();
[364]277      (*jvm).DestroyJavaVM();
278#else
[1]279      (*jvm)->DestroyJavaVM(jvm);
[364]280#endif
[9]281      return -1;
[1]282    }
283  }
[364]284#ifdef JAVA7
285      (*jvm).DestroyJavaVM();
286#else
[1]287  (*jvm)->DestroyJavaVM(jvm);
[364]288#endif
[771]289  for(i=0;i<nbs[2]+nbs[1]+nbs[0];i++){
[748]290    free(options[start+i].optionString);
291  }
[765]292#ifdef WIN32
293  free(options);
294#endif
[1]295  return res;
296}
297
[388]298/**
299 * Error handling: display stack trace in an ExceptionReport Document
[580]300 *
301 * @param env the JNI environment pointer
302 * @param main_conf the conf maps containing the main.cfg settings
[388]303 */
304void displayStack(JNIEnv *env,maps* main_conf){
305  map *tmpm=getMapFromMaps(main_conf,"main","tmpPath");
306  char tmps[1024];
307  sprintf(tmps,"%s/%d.ztmp",tmpm->value,getpid());
308  FILE* new_stdout=fopen(tmps,"wb+");
[527]309  if(new_stdout==NULL){
[781]310    map* err=createMap("text","Unable to run your service, no debug information can be provided (please verify privileges on tmpPath)");
[527]311    addToMap(err,"code","InternalError");
312    printExceptionReportResponse(main_conf,err);
313    freeMap(&err);
314    free(err);
315    return;
316  }
[388]317  fflush(stderr);
318  dup2(fileno(new_stdout),fileno(stderr));
319  fprintf(stderr,"Unable to run your java process properly: ");
320  fflush(stderr);
321#ifdef JAVA7
322  (*env).ExceptionDescribe();
323#else
324  (*env)->ExceptionDescribe(env);
325#endif
326  fflush(new_stdout);
327  fseek(new_stdout, 0, SEEK_END);
328  long flen=ftell(new_stdout);
329  fseek(new_stdout, 0, SEEK_SET);
330  char *tmps1=(char*)malloc((flen+1)*sizeof(char));
331  fread(tmps1,flen,1,new_stdout);
332  fclose(new_stdout);
333  tmps1[flen]=0;
334  map* err=createMap("text",tmps1);
335  addToMap(err,"code","InternalError");
336  printExceptionReportResponse(main_conf,err);
337  freeMap(&err);
338  free(err);
339}
340
[580]341/**
[771]342 * Create a string containing the JVM -D* options for a given map
343 * The result will be : -Dname=value
344 *
345 * @param m the map containing the option
346 * @return a char* containing the valide JVM option (-D*)
347 */
348char *parseJVMOption(map* m){
349  char *res=(char*)malloc((strlen(m->name)+strlen(m->value)+4)*sizeof(char));
350  sprintf(res,"-D%s=%s",m->name,m->value);
351  return res;
352}
353
354/**
[580]355 * Create a string containing the JVM -XX:* option for a given map
356 * Depending on the map' name:
[613]357 *  - in case the value is minus then the result will be : -XX:-name
358 *  - in case the value is plus then the result will be : -XX:+name
359 *  - in other cases the result will be : -XX:name=value
[580]360 *
361 * @param m the map containing the option
362 * @return a char* containing the valide JVM option (-XX:*)
363 */
[539]364char *parseJVMXXOption(map* m){
[747]365  char *res=(char*)malloc((strlen(m->name)+strlen(m->value)+6)*sizeof(char));
[539]366  if(strncasecmp(m->value,"minus",5)==0)
367    sprintf(res,"-XX:-%s",m->name);
[767]368  else if(strncasecmp(m->value,"plus",4)==0)
[539]369    sprintf(res,"-XX:+%s",m->name);
370  else
371    sprintf(res,"-XX:%s=%s",m->name,m->value);
372  return res;
373}
374
[580]375/**
[613]376 * Create a string containing the JVM -X** option for a given map.
377 * The result will be in the following format: -Xnamevalue
[580]378 *
379 * @param m the map containing the option
[613]380 * @return a char* containing the valide JVM option (-X**)
[580]381 */
[539]382char *parseJVMXOption(map* m){
383  char *res=(char*)malloc((strlen(m->name)+strlen(m->value)+5)*sizeof(char));
[613]384  sprintf(res,"-X%s%s",m->name,m->value);
[539]385  return res;
386}
387
[580]388/**
389 * Convert a maps to a JAVA HashMap<String,HashMap<String,String>>
390 *
391 * @param env the JNI environment pointer
392 * @param t the maps to convert
393 * @param scHashMapClass the HashMap class
394 * @param scHashMap_class the HashMap class
395 * @param scHashMap_constructor the pointer to the hashMap constructor method
396 * @return a created JAVA HashMap containing the converted maps
[781]397 * @warning make sure to free resources returned by this function
[580]398 */
[57]399jobject HashMap_FromMaps(JNIEnv *env,maps* t,jclass scHashMapClass,jclass scHashMap_class,jmethodID scHashMap_constructor){
[1]400  jobject scObject,scObject1;
401  if(scHashMap_constructor!=NULL){
[364]402#ifdef JAVA7
403    scObject = (*env).NewObject(scHashMap_class, scHashMap_constructor);
404#else
[1]405    scObject = (*env)->NewObject(env, scHashMap_class, scHashMap_constructor);
[364]406#endif
[1]407    jmethodID put_mid = 0;
408
[364]409#ifdef JAVA7
410    put_mid = (*env).GetMethodID(scHashMapClass, "put",
411                                  "(Ljava/lang/Object;Ljava/lang/Object;)"
412                                  "Ljava/lang/Object;");
413#else
[1]414    put_mid = (*env)->GetMethodID(env,scHashMapClass, "put",
415                                  "(Ljava/lang/Object;Ljava/lang/Object;)"
416                                  "Ljava/lang/Object;");
[364]417#endif
[1]418    maps* tmp=t;
419    while(tmp!=NULL){
[360]420      map* tmap=getMapType(tmp->content);
[1]421      map* tmp1=tmp->content;
[364]422#ifdef JAVA7
423      scObject1 = (*env).NewObject(scHashMap_class, scHashMap_constructor);
424#else
[1]425      scObject1 = (*env)->NewObject(env, scHashMap_class, scHashMap_constructor);
[364]426#endif
[68]427      map* sizeV=getMap(tmp1,"size");
[360]428      map* isArray=getMap(tmp1,"isArray");
429      map* alen=getMap(tmp1,"length");
[1]430      while(tmp1!=NULL){
[360]431        if(strcmp(tmp1->name,"value")==0){
432          if(isArray==NULL){
433            if(sizeV!=NULL && strcmp(tmp1->name,"value")==0){
[364]434#ifdef JAVA7
435              jbyteArray tmpData=(*env).NewByteArray(atoi(sizeV->value));
436              (*env).SetByteArrayRegion(tmpData,0,atoi(sizeV->value),(const jbyte *)tmp1->value);
[767]437              (*env).CallObjectMethod(env,scObject1, put_mid, (*env).NewStringUTF(env,tmp1->name), tmpData);
[364]438#else
[360]439              jbyteArray tmpData=(*env)->NewByteArray(env,atoi(sizeV->value));
[767]440              (*env)->SetByteArrayRegion(env,tmpData,0,atoi(sizeV->value),(jbyte*) tmp1->value);
[360]441              (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), tmpData);
[364]442#endif
[360]443            }else
[364]444#ifdef JAVA7
445              (*env).CallObjectMethod(scObject1, put_mid, (*env).NewStringUTF(tmp1->name), (*env).NewStringUTF(tmp1->value));
446#else
[360]447              (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), (*env)->NewStringUTF(env,tmp1->value));
[364]448#endif
[360]449          }
450          else{
451            int alen1=atoi(alen->value);
452            fprintf(stderr,"LENGTH %d \n",alen1);
453           
454            jclass scArrayListClass,scArrayList_class;
455            jmethodID scArrayList_constructor;
[388]456            jobject scObject2;
[364]457#ifdef JAVA7
458            scArrayListClass = (*env).FindClass("java/util/ArrayList");
459            scArrayList_class = (jclass)(*env).NewGlobalRef(scArrayListClass);
460            scArrayList_constructor = (*env).GetMethodID(scArrayList_class, "<init>", "()V");
461            jmethodID add_mid = 0;
462            scObject2 = (*env).NewObject(scArrayList_class, scArrayList_constructor);
463
464            add_mid = (*env).GetMethodID(scArrayListClass,
465                                          "add","(Ljava/lang/Object;)Z");
466#else
[360]467            scArrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
468            scArrayList_class = (*env)->NewGlobalRef(env, scArrayListClass);
469            scArrayList_constructor = (*env)->GetMethodID(env, scArrayList_class, "<init>", "()V");
470            jmethodID add_mid = 0;
471            scObject2 = (*env)->NewObject(env, scArrayList_class, scArrayList_constructor);
472
473            add_mid = (*env)->GetMethodID(env,scArrayListClass,
474                                          "add","(Ljava/lang/Object;)Z");
[364]475#endif     
[360]476            int i;
477           
478            for(i=0;i<alen1;i++){
[771]479              map* vMap=getMapArray(tmp->content,"value",i);
[360]480              map* sMap=getMapArray(tmp->content,"size",i);
481              map* mMap=getMapArray(tmp->content,tmap->value,i);
482             
483              if(sMap!=NULL && vMap!=NULL && strncmp(vMap->name,"value",5)==0){
[364]484#ifdef JAVA7
485                jbyteArray tmpData=(*env).NewByteArray(atoi(sMap->value));
486                (*env).SetByteArrayRegion(tmpData,0,atoi(sMap->value),(const jbyte *)vMap->value);
487                (*env).CallObjectMethod(scObject2, add_mid, tmpData);
488#else
[360]489                jbyteArray tmpData=(*env)->NewByteArray(env,atoi(sMap->value));
490                (*env)->SetByteArrayRegion(env,tmpData,0,atoi(sMap->value),vMap->value);
491                (*env)->CallObjectMethod(env,scObject2, add_mid, tmpData);
[364]492#endif
[360]493              }else{
[364]494#ifdef JAVA7
495                jobject tmpData=(*env).NewStringUTF(vMap->value);
496                (*env).CallObjectMethod(scObject2, add_mid, tmpData);
497#else
[360]498                jobject tmpData=(*env)->NewStringUTF(env,vMap->value);
499                (*env)->CallObjectMethod(env,scObject2, add_mid, tmpData);
[364]500#endif
[360]501              }
502             
503            }
[364]504
505#ifdef JAVA7
506            (*env).CallObjectMethod(scObject1, put_mid, (*env).NewStringUTF(tmp1->name), scObject2);
507#else       
[360]508            (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), scObject2);
[364]509#endif
510
[360]511          }
512        }
513        else
[364]514#ifdef JAVA7
515          (*env).CallObjectMethod(scObject1, put_mid, (*env).NewStringUTF(tmp1->name), (*env).NewStringUTF(tmp1->value));
516#else
[68]517          (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), (*env)->NewStringUTF(env,tmp1->value));
[364]518#endif
[1]519        tmp1=tmp1->next;
520      }
[364]521#ifdef JAVA7
522      (*env).CallObjectMethod(scObject, put_mid, (*env).NewStringUTF(tmp->name), scObject1);
523#else
[1]524      (*env)->CallObjectMethod(env,scObject, put_mid, (*env)->NewStringUTF(env,tmp->name), scObject1);
[364]525#endif
[1]526      tmp=tmp->next;
[57]527    }
[1]528    return scObject;
529  }
530  else
531    return NULL;
532}
533
[580]534/**
535 * Convert a JAVA HashMap<String,HashMap<String,String>> to a maps
536 *
537 * @param env the JNI environment pointer
538 * @param t the HashMap
539 * @param scHashMapClass the hashMap class
540 * @return a created maps containing the converted HashMap
[781]541 * @warning make sure to free resources returned by this function
[580]542 */
[57]543maps* mapsFromHashMap(JNIEnv *env,jobject t,jclass scHashMapClass){
[1]544#ifdef DEBUG
545  fprintf(stderr,"mapsFromHashMap start\n");
546#endif
547  /**
548   * What need to be done (in java).
549   * Set set = hm.entrySet();
550   * Iterator i = set.iterator();
551   * while(i.hasNext()){
552   *   Map.Entry me = (Map.Entry)i.next();
553   *   System.out.println(me.getKey() + " : " + me.getValue() );
554   * }
555   */
[640]556  jclass scSetClass,scIteratorClass,scMapEntryClass;
[68]557  jmethodID entrySet_mid,containsKey_mid,get_mid,iterator_mid,hasNext_mid,next_mid,getKey_mid,getValue_mid;
[1]558  if(scHashMapClass==NULL){
[114]559#ifdef DEBUG
[1]560    fprintf(stderr,"Unable to load java.util.HashMap\n");
[114]561#endif
[1]562    return NULL;
563  }
[364]564#ifdef JAVA7
565  entrySet_mid = (*env).GetMethodID(scHashMapClass, "entrySet", "()Ljava/util/Set;"); 
566  containsKey_mid = (*env).GetMethodID(scHashMapClass, "containsKey", "(Ljava/lang/Object;)Z");
567  get_mid = (*env).GetMethodID(scHashMapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); 
568#else
[1]569  entrySet_mid = (*env)->GetMethodID(env, scHashMapClass, "entrySet", "()Ljava/util/Set;"); 
[68]570  containsKey_mid = (*env)->GetMethodID(env, scHashMapClass, "containsKey", "(Ljava/lang/Object;)Z");
571  get_mid = (*env)->GetMethodID(env, scHashMapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); 
[364]572#endif
[114]573
[68]574  if(containsKey_mid==0){
[114]575#ifdef DEBUG
[68]576    fprintf(stderr,"unable to load containsKey from HashMap object (%d) \n",entrySet_mid);
[114]577#endif
578    return NULL;
[68]579  }
580  if(get_mid==0){
[114]581#ifdef DEBUG
[68]582    fprintf(stderr,"unable to load get from HashMap object (%d) \n",entrySet_mid);
[114]583#endif
584    return NULL;
[68]585  }
[1]586  if(entrySet_mid==0){
[114]587#ifdef DEBUG
[1]588    fprintf(stderr,"unable to load entrySet from HashMap object (%d) \n",entrySet_mid);
[114]589#endif
[1]590    return NULL;
591  }
592#ifdef DEBUG
593  else
594    fprintf(stderr,"entrySet loaded from HashMap object (%d) \n",entrySet_mid);
595#endif
596
[364]597#ifdef JAVA7
598  scSetClass = (*env).FindClass("java/util/Set");
599  iterator_mid = (*env).GetMethodID(scSetClass, "iterator", "()Ljava/util/Iterator;"); 
600#else
[1]601  scSetClass = (*env)->FindClass(env, "java/util/Set");
602  iterator_mid = (*env)->GetMethodID(env, scSetClass, "iterator", "()Ljava/util/Iterator;"); 
[364]603#endif
[1]604#ifdef DEBUG
605  fprintf(stderr,"mapsFromHashMap 1 (%d) \n",iterator_mid);
606#endif
607
[364]608#ifdef JAVA7
609  scIteratorClass = (*env).FindClass("java/util/Iterator");
610  hasNext_mid = (*env).GetMethodID(scIteratorClass, "hasNext", "()Z");
611#else
[1]612  scIteratorClass = (*env)->FindClass(env, "java/util/Iterator");
613  hasNext_mid = (*env)->GetMethodID(env, scIteratorClass, "hasNext", "()Z");
[364]614#endif
615
[1]616#ifdef DEBUG
617  fprintf(stderr,"mapsFromHashMap 2 (%d)\n",hasNext_mid);
618#endif
[364]619
620#ifdef JAVA7
621  next_mid = (*env).GetMethodID(scIteratorClass, "next", "()Ljava/lang/Object;");
622#else
[1]623  next_mid = (*env)->GetMethodID(env, scIteratorClass, "next", "()Ljava/lang/Object;");
[364]624#endif
[1]625#ifdef DEBUG
626  fprintf(stderr,"mapsFromHashMap 3 (%d)\n",next_mid);
627#endif
628
[364]629#ifdef JAVA7
630  scMapEntryClass = (*env).FindClass("java/util/Map$Entry");
631  getKey_mid = (*env).GetMethodID(scMapEntryClass, "getKey", "()Ljava/lang/Object;");
632#else
[1]633  scMapEntryClass = (*env)->FindClass(env, "java/util/Map$Entry");
634  getKey_mid = (*env)->GetMethodID(env, scMapEntryClass, "getKey", "()Ljava/lang/Object;");
[364]635#endif
[1]636#ifdef DEBUG
637  fprintf(stderr,"mapsFromHashMap 4 (%d)\n",getKey_mid);
638#endif
[364]639#ifdef JAVA7
640  getValue_mid = (*env).GetMethodID(scMapEntryClass, "getValue", "()Ljava/lang/Object;");
641#else
[1]642  getValue_mid = (*env)->GetMethodID(env, scMapEntryClass, "getValue", "()Ljava/lang/Object;");
[364]643#endif
[1]644#ifdef DEBUG
645  fprintf(stderr,"mapsFromHashMap 5 (%d)\n",getValue_mid);
646#endif
647
[364]648#ifdef JAVA7
649  jobject final_set=(*env).CallObjectMethod(t,entrySet_mid);
650  jobject final_iterator=(*env).CallObjectMethod(final_set,iterator_mid);
651#else
[1]652  jobject final_set=(*env)->CallObjectMethod(env,t,entrySet_mid);
653  jobject final_iterator=(*env)->CallObjectMethod(env,final_set,iterator_mid);
[364]654#endif
[1]655
656  maps* final_res=NULL;
657  map* res=NULL;
[364]658#ifdef JAVA7
659  while((*env).CallBooleanMethod(final_iterator,hasNext_mid)){
660    jobject tmp=(*env).CallObjectMethod(final_iterator,next_mid);
661
662    jobject imap=(*env).CallObjectMethod(tmp,getValue_mid);
663    jobject set=(*env).CallObjectMethod(imap,entrySet_mid);
664    jobject iterator=(*env).CallObjectMethod(set,iterator_mid);
665
666#else
[1]667  while((*env)->CallBooleanMethod(env,final_iterator,hasNext_mid)){
668    jobject tmp=(*env)->CallObjectMethod(env,final_iterator,next_mid);
669
670    jobject imap=(*env)->CallObjectMethod(env,tmp,getValue_mid);
671    jobject set=(*env)->CallObjectMethod(env,imap,entrySet_mid);
672    jobject iterator=(*env)->CallObjectMethod(env,set,iterator_mid);
[57]673
[364]674#endif
[68]675    int size=-1;
[364]676#ifdef JAVA7
677    if((*env).CallBooleanMethod(imap,containsKey_mid,(*env).NewStringUTF("size"))){
678      jobject sizeV=(*env).CallObjectMethod(imap, get_mid,(*env).NewStringUTF("size"));
679      const char* sizeVS=(*env).GetStringUTFChars((jstring)sizeV, NULL);
680#else
[68]681    if((*env)->CallBooleanMethod(env,imap,containsKey_mid,(*env)->NewStringUTF(env,"size"))){
682      jobject sizeV=(*env)->CallObjectMethod(env, imap, get_mid,(*env)->NewStringUTF(env,"size"));
[114]683      const char* sizeVS=(*env)->GetStringUTFChars(env, sizeV, NULL);
[364]684#endif
[68]685      size=atoi(sizeVS);
686      fprintf(stderr,"SIZE : %s\n",sizeVS);
[364]687#ifdef JAVA7
688      (*env).ReleaseStringUTFChars((jstring)sizeV, sizeVS);
689#else
[114]690      (*env)->ReleaseStringUTFChars(env, sizeV, sizeVS);
[364]691#endif
[68]692    }
693   
[364]694#ifdef JAVA7
695    while((*env).CallBooleanMethod(iterator,hasNext_mid)){
696      jobject tmp1=(*env).CallObjectMethod(iterator,next_mid);
697      jobject jk=(*env).CallObjectMethod(tmp1,getKey_mid);
698      jobject jv=(*env).CallObjectMethod(tmp1,getValue_mid);
699
700      const char* jkd=(*env).GetStringUTFChars((jstring)jk, NULL);
701#else
[1]702    while((*env)->CallBooleanMethod(env,iterator,hasNext_mid)){
703      jobject tmp1=(*env)->CallObjectMethod(env,iterator,next_mid);
704      jobject jk=(*env)->CallObjectMethod(env,tmp1,getKey_mid);
705      jobject jv=(*env)->CallObjectMethod(env,tmp1,getValue_mid);
706
[114]707      const char* jkd=(*env)->GetStringUTFChars(env, jk, NULL);
[364]708#endif
[68]709      if(size>=0 && strcmp(jkd,"value")==0){
[364]710#ifdef JAVA7
711        jobject value=(jobject)(*env).GetByteArrayElements((jbyteArray)jv, NULL);
712#else
[68]713        jobject value=(*env)->GetByteArrayElements(env, jv, NULL);
[364]714#endif
[68]715        if(res==NULL){
716          res=createMap(jkd,"");
717        }else{
718          addToMap(res,jkd,"");
719        }
720        map* tmpR=getMap(res,"value");
721        free(tmpR->value);
722        tmpR->value=(char*)malloc((size+1)*sizeof(char));
723        memmove(tmpR->value,value,size*sizeof(char));
724        tmpR->value[size]=0;
[114]725        char tmp[128];
726        sprintf(tmp,"%d",size);
727        addToMap(res,"size",tmp);
[68]728      }
729      else{
[364]730#ifdef JAVA7
731        const char* jvd=(*env).GetStringUTFChars((jstring)jv, NULL);
732#else
[114]733        const char* jvd=(*env)->GetStringUTFChars(env, jv, NULL);
[364]734#endif
[68]735        if(res==NULL){
736          res=createMap(jkd,jvd);
737        }else{
738          addToMap(res,jkd,jvd);
739        }
[364]740#ifdef JAVA7
741        (*env).ReleaseStringUTFChars((jstring)jv, jvd);
742#else
[114]743        (*env)->ReleaseStringUTFChars(env, jv, jvd);
[364]744#endif
[68]745      }
[59]746
[364]747#ifdef JAVA7
748      (*env).ReleaseStringUTFChars((jstring)jk, jkd);
749#else
[114]750      (*env)->ReleaseStringUTFChars(env, jk, jkd);
[364]751#endif
[59]752
[1]753    }
[364]754#ifdef JAVA7
755    jobject jk=(*env).CallObjectMethod(tmp,getKey_mid);
756#else
[1]757    jobject jk=(*env)->CallObjectMethod(env,tmp,getKey_mid);
[364]758#endif
[1]759    maps* cmap=(maps*)malloc(sizeof(maps));
[364]760#ifdef JAVA7
761    cmap->name=(char*)(*env).GetStringUTFChars((jstring)jk, NULL);
762#else
[1]763    cmap->name=(*env)->GetStringUTFChars(env, jk, NULL);
[364]764#endif
[57]765#ifdef DEBUG
766    fprintf(stderr," / %s \n",cmap->name);
767#endif
[1]768    cmap->content=res;
769    cmap->next=NULL;
[57]770    if(final_res==NULL)
[9]771      final_res=dupMaps(&cmap);
[57]772    else
[9]773      addMapsToMaps(&final_res,cmap);
774    freeMaps(&cmap);
775    free(cmap);
776    cmap=NULL;
[1]777    res=NULL;
778  }
779#ifdef DEBUG
780  fprintf(stderr,"mapsFromHashMap end\n");
781#endif
782
783  return final_res;
784}
[527]785
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png