~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to ogr/ogrsf_frmts/mdb/ogrmdbjackcess.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * $Id: ogrmdbjackcess.cpp 22156 2011-04-13 20:08:07Z rouault $
 
3
 *
 
4
 * Project:  OpenGIS Simple Features Reference Implementation
 
5
 * Purpose:  Implements OGRMDBJavaEnv class.
 
6
 * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
 
7
 *
 
8
 ******************************************************************************
 
9
 * Copyright (c) 2011, Even Rouault, <even dot rouault at mines dash paris dot org>
 
10
 *
 
11
 * Permission is hereby granted, free of charge, to any person obtaining a
 
12
 * copy of this software and associated documentation files (the "Software"),
 
13
 * to deal in the Software without restriction, including without limitation
 
14
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
15
 * and/or sell copies of the Software, and to permit persons to whom the
 
16
 * Software is furnished to do so, subject to the following conditions:
 
17
 *
 
18
 * The above copyright notice and this permission notice shall be included
 
19
 * in all copies or substantial portions of the Software.
 
20
 *
 
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
22
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
24
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
26
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
27
 * DEALINGS IN THE SOFTWARE.
 
28
 ****************************************************************************/
 
29
 
 
30
#include "ogr_mdb.h"
 
31
 
 
32
CPL_CVSID("$Id: ogrmdbjackcess.cpp 22156 2011-04-13 20:08:07Z rouault $");
 
33
 
 
34
static JavaVM *jvm_static = NULL;
 
35
static JNIEnv *env_static = NULL;
 
36
 
 
37
/************************************************************************/
 
38
/*                         OGRMDBJavaEnv()                              */
 
39
/************************************************************************/
 
40
 
 
41
OGRMDBJavaEnv::OGRMDBJavaEnv()
 
42
{
 
43
    jvm = NULL;
 
44
    env = NULL;
 
45
    bCalledFromJava = FALSE;
 
46
 
 
47
    byteArray_class = NULL;
 
48
 
 
49
    file_class = NULL;
 
50
    file_constructor = NULL;
 
51
    database_class = NULL;
 
52
    database_open = NULL;
 
53
    database_close = NULL;
 
54
    database_getTableNames = NULL;
 
55
    database_getTable = NULL;
 
56
 
 
57
    table_class = NULL;
 
58
    table_getColumns = NULL;
 
59
    table_iterator = NULL;
 
60
    table_getRowCount = NULL;
 
61
 
 
62
    column_class = NULL;
 
63
    column_getName = NULL;
 
64
    column_getType = NULL;
 
65
    column_getLength = NULL;
 
66
    column_isVariableLength = NULL;
 
67
 
 
68
    datatype_class = NULL;
 
69
    datatype_getValue = NULL;
 
70
 
 
71
    list_class = NULL;
 
72
    list_iterator = NULL;
 
73
 
 
74
    set_class = NULL;
 
75
    set_iterator = NULL;
 
76
 
 
77
    map_class = NULL;
 
78
    map_get = NULL;
 
79
 
 
80
    iterator_class = NULL;
 
81
    iterator_hasNext = NULL;
 
82
    iterator_next = NULL;
 
83
 
 
84
    object_class = NULL;
 
85
    object_toString = NULL;
 
86
    object_getClass = NULL;
 
87
 
 
88
    boolean_class = NULL;
 
89
    boolean_booleanValue = NULL;
 
90
 
 
91
    byte_class = NULL;
 
92
    byte_byteValue = NULL;
 
93
 
 
94
    short_class = NULL;
 
95
    short_shortValue = NULL;
 
96
 
 
97
    integer_class = NULL;
 
98
    integer_intValue = NULL;
 
99
 
 
100
    float_class = NULL;
 
101
    float_floatValue = NULL;
 
102
 
 
103
    double_class = NULL;
 
104
    double_doubleValue = NULL;
 
105
}
 
106
 
 
107
/************************************************************************/
 
108
/*                        ~OGRMDBJavaEnv()                              */
 
109
/************************************************************************/
 
110
 
 
111
OGRMDBJavaEnv::~OGRMDBJavaEnv()
 
112
{
 
113
    if (jvm)
 
114
    {
 
115
        env->DeleteLocalRef(byteArray_class);
 
116
 
 
117
        env->DeleteLocalRef(file_class);
 
118
        env->DeleteLocalRef(database_class);
 
119
 
 
120
        env->DeleteLocalRef(table_class);
 
121
 
 
122
        env->DeleteLocalRef(column_class);
 
123
 
 
124
        env->DeleteLocalRef(datatype_class);
 
125
 
 
126
        env->DeleteLocalRef(list_class);
 
127
 
 
128
        env->DeleteLocalRef(set_class);
 
129
 
 
130
        env->DeleteLocalRef(map_class);
 
131
 
 
132
        env->DeleteLocalRef(iterator_class);
 
133
 
 
134
        env->DeleteLocalRef(object_class);
 
135
 
 
136
        env->DeleteLocalRef(boolean_class);
 
137
        env->DeleteLocalRef(byte_class);
 
138
        env->DeleteLocalRef(short_class);
 
139
        env->DeleteLocalRef(integer_class);
 
140
        env->DeleteLocalRef(float_class);
 
141
        env->DeleteLocalRef(double_class);
 
142
 
 
143
        /*if (!bCalledFromJava)
 
144
        {
 
145
            CPLDebug("MDB", "Destroying JVM");
 
146
            int ret = jvm->DestroyJavaVM();
 
147
            CPLDebug("MDB", "ret=%d", ret);
 
148
        }*/
 
149
    }
 
150
}
 
151
 
 
152
#define CHECK(x, y) do {x = y; if (!x) { CPLError(CE_Failure, CPLE_AppDefined, #y " failed"); return FALSE;} } while(0)
 
153
 
 
154
/************************************************************************/
 
155
/*                              Init()                                  */
 
156
/************************************************************************/
 
157
 
 
158
int OGRMDBJavaEnv::Init()
 
159
{
 
160
    if (jvm_static == NULL)
 
161
    {
 
162
        JavaVM* vmBuf[1];
 
163
        jsize nVMs;
 
164
 
 
165
        /* Are we already called from Java ? */
 
166
        if (JNI_GetCreatedJavaVMs(vmBuf, 1, &nVMs) == JNI_OK && nVMs == 1)
 
167
        {
 
168
            jvm = vmBuf[0];
 
169
            if (jvm->GetEnv((void **)&env, JNI_VERSION_1_2) == JNI_OK)
 
170
            {
 
171
                bCalledFromJava = TRUE;
 
172
            }
 
173
            else
 
174
            {
 
175
                jvm = NULL;
 
176
                env = NULL;
 
177
            }
 
178
        }
 
179
        else
 
180
        {
 
181
            JavaVMInitArgs args;
 
182
            JavaVMOption options[1];
 
183
            args.version = JNI_VERSION_1_2;
 
184
            const char* pszClassPath = CPLGetConfigOption("CLASSPATH", NULL);
 
185
            CPLString osClassPathOption;
 
186
            if (pszClassPath)
 
187
            {
 
188
                args.nOptions = 1;
 
189
                osClassPathOption.Printf("-Djava.class.path=%s", pszClassPath);
 
190
                options[0].optionString = (char*) osClassPathOption.c_str();
 
191
                args.options = options;
 
192
            }
 
193
            else
 
194
                args.nOptions = 0;
 
195
            args.ignoreUnrecognized = JNI_FALSE;
 
196
 
 
197
            int ret = JNI_CreateJavaVM(&jvm, (void **)&env, &args);
 
198
            if (ret != 0 || jvm == NULL || env == NULL)
 
199
            {
 
200
                CPLError(CE_Failure, CPLE_AppDefined, "JNI_CreateJavaVM failed (%d)", ret);
 
201
                return FALSE;
 
202
            }
 
203
 
 
204
            jvm_static = jvm;
 
205
            env_static = env;
 
206
        }
 
207
    }
 
208
    else
 
209
    {
 
210
        jvm = jvm_static;
 
211
        env = env_static;
 
212
    }
 
213
 
 
214
    CHECK(byteArray_class, env->FindClass("[B"));
 
215
    CHECK(file_class, env->FindClass("java/io/File"));
 
216
    CHECK(file_constructor, env->GetMethodID(file_class, "<init>", "(Ljava/lang/String;)V"));
 
217
    CHECK(database_class, env->FindClass("com/healthmarketscience/jackcess/Database"));
 
218
 
 
219
    CHECK(database_open, env->GetStaticMethodID(database_class, "open", "(Ljava/io/File;Z)Lcom/healthmarketscience/jackcess/Database;"));
 
220
    CHECK(database_close, env->GetMethodID(database_class, "close", "()V"));
 
221
    CHECK(database_getTableNames, env->GetMethodID(database_class, "getTableNames", "()Ljava/util/Set;"));
 
222
    CHECK(database_getTable, env->GetMethodID(database_class, "getTable", "(Ljava/lang/String;)Lcom/healthmarketscience/jackcess/Table;"));
 
223
 
 
224
    CHECK(table_class, env->FindClass("com/healthmarketscience/jackcess/Table"));
 
225
    CHECK(table_getColumns, env->GetMethodID(table_class, "getColumns", "()Ljava/util/List;"));
 
226
    CHECK(table_iterator, env->GetMethodID(table_class, "iterator", "()Ljava/util/Iterator;"));
 
227
    CHECK(table_getRowCount, env->GetMethodID(table_class, "getRowCount", "()I"));
 
228
 
 
229
    CHECK(column_class, env->FindClass("com/healthmarketscience/jackcess/Column"));
 
230
    CHECK(column_getName, env->GetMethodID(column_class, "getName", "()Ljava/lang/String;"));
 
231
    CHECK(column_getType, env->GetMethodID(column_class, "getType", "()Lcom/healthmarketscience/jackcess/DataType;"));
 
232
    CHECK(column_getLength, env->GetMethodID(column_class, "getLength", "()S"));
 
233
    CHECK(column_isVariableLength, env->GetMethodID(column_class, "isVariableLength", "()Z"));
 
234
 
 
235
    CHECK(datatype_class, env->FindClass("com/healthmarketscience/jackcess/DataType"));
 
236
    CHECK(datatype_getValue, env->GetMethodID(datatype_class, "getValue", "()B"));
 
237
 
 
238
    CHECK(list_class, env->FindClass("java/util/List"));
 
239
    CHECK(list_iterator, env->GetMethodID(list_class, "iterator", "()Ljava/util/Iterator;"));
 
240
 
 
241
    CHECK(set_class, env->FindClass("java/util/Set"));
 
242
    CHECK(set_iterator, env->GetMethodID(set_class, "iterator", "()Ljava/util/Iterator;"));
 
243
 
 
244
    CHECK(map_class, env->FindClass("java/util/Map"));
 
245
    CHECK(map_get, env->GetMethodID(map_class, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"));
 
246
 
 
247
    CHECK(iterator_class,  env->FindClass("java/util/Iterator"));
 
248
    CHECK(iterator_hasNext, env->GetMethodID(iterator_class, "hasNext", "()Z"));
 
249
    CHECK(iterator_next, env->GetMethodID(iterator_class, "next", "()Ljava/lang/Object;"));
 
250
 
 
251
    CHECK(object_class,  env->FindClass("java/lang/Object"));
 
252
    CHECK(object_toString, env->GetMethodID(object_class, "toString", "()Ljava/lang/String;"));
 
253
    CHECK(object_getClass, env->GetMethodID(object_class, "getClass", "()Ljava/lang/Class;"));
 
254
 
 
255
    CHECK(boolean_class,  env->FindClass("java/lang/Boolean"));
 
256
    CHECK(boolean_booleanValue, env->GetMethodID(boolean_class, "booleanValue", "()Z"));
 
257
 
 
258
    CHECK(byte_class,  env->FindClass("java/lang/Byte"));
 
259
    CHECK(byte_byteValue, env->GetMethodID(byte_class, "byteValue", "()B"));
 
260
 
 
261
    CHECK(short_class,  env->FindClass("java/lang/Short"));
 
262
    CHECK(short_shortValue, env->GetMethodID(short_class, "shortValue", "()S"));
 
263
 
 
264
    CHECK(integer_class,  env->FindClass("java/lang/Integer"));
 
265
    CHECK(integer_intValue, env->GetMethodID(integer_class, "intValue", "()I"));
 
266
 
 
267
    CHECK(float_class,  env->FindClass("java/lang/Float"));
 
268
    CHECK(float_floatValue, env->GetMethodID(float_class, "floatValue", "()F"));
 
269
 
 
270
    CHECK(double_class,  env->FindClass("java/lang/Double"));
 
271
    CHECK(double_doubleValue, env->GetMethodID(integer_class, "doubleValue", "()D"));
 
272
 
 
273
    return TRUE;
 
274
}
 
275
 
 
276
 
 
277
/************************************************************************/
 
278
/*                       ExceptionOccured()                             */
 
279
/************************************************************************/
 
280
 
 
281
int OGRMDBJavaEnv::ExceptionOccured()
 
282
{
 
283
    jthrowable exc = env->ExceptionOccurred();
 
284
    if (exc)
 
285
    {
 
286
         env->ExceptionDescribe();
 
287
         env->ExceptionClear();
 
288
         return TRUE;
 
289
    }
 
290
    return FALSE;
 
291
}
 
292
 
 
293
 
 
294
/************************************************************************/
 
295
/*                           OGRMDBDatabase()                           */
 
296
/************************************************************************/
 
297
 
 
298
OGRMDBDatabase::OGRMDBDatabase()
 
299
{
 
300
    env = NULL;
 
301
    database = NULL;
 
302
}
 
303
 
 
304
/************************************************************************/
 
305
/*                          ~OGRMDBDatabase()                           */
 
306
/************************************************************************/
 
307
 
 
308
OGRMDBDatabase::~OGRMDBDatabase()
 
309
{
 
310
    if (database)
 
311
    {
 
312
        CPLDebug("MDB", "Closing database");
 
313
        env->env->CallVoidMethod(database, env->database_close);
 
314
 
 
315
        env->env->DeleteGlobalRef(database);
 
316
    }
 
317
}
 
318
 
 
319
/************************************************************************/
 
320
/*                               Open()                                 */
 
321
/************************************************************************/
 
322
 
 
323
OGRMDBDatabase* OGRMDBDatabase::Open(OGRMDBJavaEnv* env, const char* pszName)
 
324
{
 
325
    jstring jstr = env->env->NewStringUTF(pszName);
 
326
    jobject file = env->env->NewObject(env->file_class, env->file_constructor, jstr);
 
327
    if (env->ExceptionOccured()) return NULL;
 
328
    env->env->ReleaseStringUTFChars(jstr, NULL);
 
329
 
 
330
    jobject database = env->env->CallStaticObjectMethod(env->database_class, env->database_open, file, JNI_TRUE);
 
331
 
 
332
    env->env->DeleteLocalRef(file);
 
333
 
 
334
    if (env->ExceptionOccured()) return NULL;
 
335
    if (database == NULL)
 
336
        return NULL;
 
337
 
 
338
    OGRMDBDatabase* poDB = new OGRMDBDatabase();
 
339
    poDB->env = env;
 
340
    poDB->database = env->env->NewGlobalRef(database);
 
341
    env->env->DeleteLocalRef(database);
 
342
    return poDB;
 
343
}
 
344
 
 
345
/************************************************************************/
 
346
/*                        FetchTableNames()                             */
 
347
/************************************************************************/
 
348
 
 
349
int OGRMDBDatabase::FetchTableNames()
 
350
{
 
351
    if (env->bCalledFromJava)
 
352
        env->Init();
 
353
 
 
354
    jobject table_set = env->env->CallObjectMethod(database, env->database_getTableNames);
 
355
    if (env->ExceptionOccured()) return FALSE;
 
356
    jobject iterator = env->env->CallObjectMethod(table_set, env->set_iterator);
 
357
    if (env->ExceptionOccured()) return FALSE;
 
358
 
 
359
    while( env->env->CallBooleanMethod(iterator, env->iterator_hasNext) )
 
360
    {
 
361
        if (env->ExceptionOccured()) return FALSE;
 
362
        jstring table_name_jstring = (jstring) env->env->CallObjectMethod(iterator, env->iterator_next);
 
363
        if (env->ExceptionOccured()) return FALSE;
 
364
        jboolean is_copy;
 
365
        const char* table_name_str = env->env->GetStringUTFChars(table_name_jstring, &is_copy);
 
366
 
 
367
        apoTableNames.push_back(table_name_str);
 
368
        //CPLDebug("MDB", "Table %s", table_name_str);
 
369
 
 
370
        env->env->ReleaseStringUTFChars(table_name_jstring, table_name_str);
 
371
        env->env->DeleteLocalRef(table_name_jstring);
 
372
    }
 
373
    env->env->DeleteLocalRef(iterator);
 
374
    env->env->DeleteLocalRef(table_set);
 
375
    return TRUE;
 
376
}
 
377
 
 
378
/************************************************************************/
 
379
/*                            GetTable()                                */
 
380
/************************************************************************/
 
381
 
 
382
OGRMDBTable* OGRMDBDatabase::GetTable(const char* pszTableName)
 
383
{
 
384
    if (env->bCalledFromJava)
 
385
        env->Init();
 
386
 
 
387
    jstring table_name_jstring = env->env->NewStringUTF(pszTableName);
 
388
    jobject table = env->env->CallObjectMethod(database, env->database_getTable, table_name_jstring);
 
389
    if (env->ExceptionOccured()) return NULL;
 
390
    env->env->DeleteLocalRef(table_name_jstring);
 
391
 
 
392
    if (!table)
 
393
        return NULL;
 
394
 
 
395
    jobject global_table = env->env->NewGlobalRef(table);
 
396
    env->env->DeleteLocalRef(table);
 
397
    table = global_table;
 
398
 
 
399
    OGRMDBTable* poTable = new OGRMDBTable(env, this, table, pszTableName);
 
400
    if (!poTable->FetchColumns())
 
401
    {
 
402
        delete poTable;
 
403
        return NULL;
 
404
    }
 
405
    return poTable;
 
406
}
 
407
 
 
408
/************************************************************************/
 
409
/*                           OGRMDBTable()                              */
 
410
/************************************************************************/
 
411
 
 
412
OGRMDBTable::OGRMDBTable(OGRMDBJavaEnv* env, OGRMDBDatabase* poDB, jobject table, const char* pszTableName )
 
413
{
 
414
    this->env = env;
 
415
    this->poDB = poDB;
 
416
    this->table = table;
 
417
    osTableName = pszTableName;
 
418
    table_iterator_obj = NULL;
 
419
    row = NULL;
 
420
}
 
421
 
 
422
/************************************************************************/
 
423
/*                          ~OGRMDBTable()                              */
 
424
/************************************************************************/
 
425
 
 
426
OGRMDBTable::~OGRMDBTable()
 
427
{
 
428
    if (env)
 
429
    {
 
430
        //CPLDebug("MDB", "Freeing table %s", osTableName.c_str());
 
431
        if (env->bCalledFromJava)
 
432
            env->Init();
 
433
 
 
434
        int i;
 
435
        for(i=0;i<(int)apoColumnNameObjects.size();i++)
 
436
            env->env->DeleteGlobalRef(apoColumnNameObjects[i]);
 
437
 
 
438
        env->env->DeleteGlobalRef(table_iterator_obj);
 
439
        env->env->DeleteGlobalRef(row);
 
440
        env->env->DeleteGlobalRef(table);
 
441
    }
 
442
}
 
443
 
 
444
/************************************************************************/
 
445
/*                          FetchColumns()                              */
 
446
/************************************************************************/
 
447
 
 
448
int OGRMDBTable::FetchColumns()
 
449
{
 
450
    if (env->bCalledFromJava)
 
451
        env->Init();
 
452
 
 
453
    jobject column_lists = env->env->CallObjectMethod(table, env->table_getColumns);
 
454
    if (env->ExceptionOccured()) return FALSE;
 
455
 
 
456
    jobject iterator_cols = env->env->CallObjectMethod(column_lists, env->list_iterator);
 
457
    if (env->ExceptionOccured()) return FALSE;
 
458
 
 
459
    while( env->env->CallBooleanMethod(iterator_cols, env->iterator_hasNext) )
 
460
    {
 
461
        if (env->ExceptionOccured()) return FALSE;
 
462
 
 
463
        jobject column = env->env->CallObjectMethod(iterator_cols, env->iterator_next);
 
464
        if (env->ExceptionOccured()) return FALSE;
 
465
 
 
466
        jstring column_name_jstring = (jstring) env->env->CallObjectMethod(column, env->column_getName);
 
467
        if (env->ExceptionOccured()) return FALSE;
 
468
        jboolean is_copy;
 
469
        const char* column_name_str = env->env->GetStringUTFChars(column_name_jstring, &is_copy);
 
470
        apoColumnNames.push_back(column_name_str);
 
471
        env->env->ReleaseStringUTFChars(column_name_jstring, column_name_str);
 
472
 
 
473
        apoColumnNameObjects.push_back((jstring) env->env->NewGlobalRef(column_name_jstring));
 
474
        env->env->DeleteLocalRef(column_name_jstring);
 
475
 
 
476
        jobject column_type = env->env->CallObjectMethod(column, env->column_getType);
 
477
        if (env->ExceptionOccured()) return FALSE;
 
478
        int type = env->env->CallByteMethod(column_type, env->datatype_getValue);
 
479
        if (env->ExceptionOccured()) return FALSE;
 
480
        apoColumnTypes.push_back(type);
 
481
 
 
482
        int isvariablelength = env->env->CallBooleanMethod(column, env->column_isVariableLength);
 
483
        if (env->ExceptionOccured()) return FALSE;
 
484
        if (!isvariablelength)
 
485
        {
 
486
            int length = env->env->CallShortMethod(column, env->column_getLength);
 
487
            if (env->ExceptionOccured()) return FALSE;
 
488
            apoColumnLengths.push_back(length);
 
489
        }
 
490
        else
 
491
            apoColumnLengths.push_back(0);
 
492
 
 
493
        //CPLDebug("MDB", "Column %s, type = %d", apoColumnNames[apoColumnNames.size()-1].c_str(), type);
 
494
 
 
495
        env->env->DeleteLocalRef(column_type);
 
496
 
 
497
        env->env->DeleteLocalRef(column);
 
498
    }
 
499
    env->env->DeleteLocalRef(iterator_cols);
 
500
    env->env->DeleteLocalRef(column_lists);
 
501
 
 
502
    return TRUE;
 
503
}
 
504
 
 
505
/************************************************************************/
 
506
/*                          ResetReading()                              */
 
507
/************************************************************************/
 
508
 
 
509
void OGRMDBTable::ResetReading()
 
510
{
 
511
    if (env->bCalledFromJava)
 
512
        env->Init();
 
513
 
 
514
    env->env->DeleteGlobalRef(table_iterator_obj);
 
515
    table_iterator_obj = NULL;
 
516
    env->env->DeleteGlobalRef(row);
 
517
    row = NULL;
 
518
}
 
519
 
 
520
/************************************************************************/
 
521
/*                           GetNextRow()                               */
 
522
/************************************************************************/
 
523
 
 
524
int OGRMDBTable::GetNextRow()
 
525
{
 
526
    if (env->bCalledFromJava)
 
527
        env->Init();
 
528
 
 
529
    if (table_iterator_obj == NULL)
 
530
    {
 
531
        table_iterator_obj = env->env->CallObjectMethod(table, env->table_iterator);
 
532
        if (env->ExceptionOccured()) return FALSE;
 
533
        if (table_iterator_obj)
 
534
        {
 
535
            jobject global_table_iterator_obj = env->env->NewGlobalRef(table_iterator_obj);
 
536
            env->env->DeleteLocalRef(table_iterator_obj);
 
537
            table_iterator_obj = global_table_iterator_obj;
 
538
        }
 
539
    }
 
540
    if (table_iterator_obj == NULL)
 
541
        return FALSE;
 
542
 
 
543
    if (!env->env->CallBooleanMethod(table_iterator_obj, env->iterator_hasNext))
 
544
        return FALSE;
 
545
    if (env->ExceptionOccured()) return FALSE;
 
546
 
 
547
    if (row)
 
548
    {
 
549
        env->env->DeleteGlobalRef(row);
 
550
        row = NULL;
 
551
    }
 
552
 
 
553
    row = env->env->CallObjectMethod(table_iterator_obj, env->iterator_next);
 
554
    if (env->ExceptionOccured()) return FALSE;
 
555
    if (row == NULL)
 
556
        return FALSE;
 
557
 
 
558
    jobject global_row = env->env->NewGlobalRef(row);
 
559
    env->env->DeleteLocalRef(row);
 
560
    row = global_row;
 
561
 
 
562
    return TRUE;
 
563
}
 
564
 
 
565
/************************************************************************/
 
566
/*                          GetColumnVal()                              */
 
567
/************************************************************************/
 
568
 
 
569
jobject OGRMDBTable::GetColumnVal(int iCol)
 
570
{
 
571
    if (row == NULL)
 
572
        return NULL;
 
573
 
 
574
    jobject val = env->env->CallObjectMethod(row, env->map_get, apoColumnNameObjects[iCol]);
 
575
    if (env->ExceptionOccured()) return NULL;
 
576
    return val;
 
577
}
 
578
 
 
579
/************************************************************************/
 
580
/*                        GetColumnAsString()                           */
 
581
/************************************************************************/
 
582
 
 
583
char* OGRMDBTable::GetColumnAsString(int iCol)
 
584
{
 
585
    jobject val = GetColumnVal(iCol);
 
586
    if (!val) return NULL;
 
587
 
 
588
    jstring val_jstring = (jstring) env->env->CallObjectMethod(val, env->object_toString);
 
589
    if (env->ExceptionOccured()) return NULL;
 
590
    jboolean is_copy;
 
591
    const char* val_str = env->env->GetStringUTFChars(val_jstring, &is_copy);
 
592
    char* dup_str = (val_str) ? CPLStrdup(val_str) : NULL;
 
593
    env->env->ReleaseStringUTFChars(val_jstring, val_str);
 
594
    env->env->DeleteLocalRef(val_jstring);
 
595
 
 
596
    env->env->DeleteLocalRef(val);
 
597
 
 
598
    return dup_str;
 
599
}
 
600
 
 
601
/************************************************************************/
 
602
/*                          GetColumnAsInt()                            */
 
603
/************************************************************************/
 
604
 
 
605
int OGRMDBTable::GetColumnAsInt(int iCol)
 
606
{
 
607
    jobject val = GetColumnVal(iCol);
 
608
    if (!val) return 0;
 
609
 
 
610
    int int_val = 0;
 
611
    if (apoColumnTypes[iCol] == MDB_Boolean)
 
612
        int_val = env->env->CallBooleanMethod(val, env->boolean_booleanValue);
 
613
    else if (apoColumnTypes[iCol] == MDB_Byte)
 
614
        int_val = env->env->CallByteMethod(val, env->byte_byteValue);
 
615
    else if (apoColumnTypes[iCol] == MDB_Short)
 
616
        int_val = env->env->CallShortMethod(val, env->short_shortValue);
 
617
    else if (apoColumnTypes[iCol] == MDB_Int)
 
618
        int_val = env->env->CallIntMethod(val, env->integer_intValue);
 
619
    if (env->ExceptionOccured()) return 0;
 
620
 
 
621
    env->env->DeleteLocalRef(val);
 
622
 
 
623
    return int_val;
 
624
}
 
625
 
 
626
/************************************************************************/
 
627
/*                        GetColumnAsDouble()                           */
 
628
/************************************************************************/
 
629
 
 
630
double OGRMDBTable::GetColumnAsDouble(int iCol)
 
631
{
 
632
    jobject val = GetColumnVal(iCol);
 
633
    if (!val) return 0;
 
634
 
 
635
    double double_val = 0;
 
636
    if (apoColumnTypes[iCol] == MDB_Double)
 
637
        double_val = env->env->CallDoubleMethod(val, env->double_doubleValue);
 
638
    else if (apoColumnTypes[iCol] == MDB_Float)
 
639
        double_val = env->env->CallFloatMethod(val, env->float_floatValue);
 
640
    if (env->ExceptionOccured()) return 0;
 
641
 
 
642
    env->env->DeleteLocalRef(val);
 
643
 
 
644
    return double_val;
 
645
}
 
646
 
 
647
/************************************************************************/
 
648
/*                        GetColumnAsBinary()                           */
 
649
/************************************************************************/
 
650
 
 
651
GByte* OGRMDBTable::GetColumnAsBinary(int iCol, int* pnBytes)
 
652
{
 
653
    *pnBytes = 0;
 
654
 
 
655
    jobject val = GetColumnVal(iCol);
 
656
    if (!val) return NULL;
 
657
 
 
658
    if (!env->env->IsInstanceOf(val, env->byteArray_class))
 
659
        return NULL;
 
660
 
 
661
    jbyteArray byteArray = (jbyteArray) val;
 
662
    *pnBytes = env->env->GetArrayLength(byteArray);
 
663
    if (env->ExceptionOccured()) return NULL;
 
664
    jboolean is_copy;
 
665
    jbyte* elts = env->env->GetByteArrayElements(byteArray, &is_copy);
 
666
    if (env->ExceptionOccured()) return NULL;
 
667
 
 
668
    GByte* pData = (GByte*)CPLMalloc(*pnBytes);
 
669
    memcpy(pData, elts, *pnBytes);
 
670
 
 
671
    env->env->ReleaseByteArrayElements(byteArray, elts, JNI_ABORT);
 
672
 
 
673
    env->env->DeleteLocalRef(val);
 
674
 
 
675
    return pData;
 
676
}
 
677
 
 
678
/************************************************************************/
 
679
/*                              DumpTable()                             */
 
680
/************************************************************************/
 
681
 
 
682
void OGRMDBTable::DumpTable()
 
683
{
 
684
    ResetReading();
 
685
    int iRow = 0;
 
686
    int nCols = apoColumnNames.size();
 
687
    while(GetNextRow())
 
688
    {
 
689
        printf("Row = %d\n", iRow ++);
 
690
        for(int i=0;i<nCols;i++)
 
691
        {
 
692
            printf("%s = ", apoColumnNames[i].c_str());
 
693
            if (apoColumnTypes[i] == MDB_Float ||
 
694
                apoColumnTypes[i] == MDB_Double)
 
695
            {
 
696
                printf("%.15f\n", GetColumnAsDouble(i));
 
697
            }
 
698
            else if (apoColumnTypes[i] == MDB_Boolean ||
 
699
                     apoColumnTypes[i] == MDB_Byte ||
 
700
                     apoColumnTypes[i] == MDB_Short ||
 
701
                     apoColumnTypes[i] == MDB_Int)
 
702
            {
 
703
                printf("%d\n", GetColumnAsInt(i));
 
704
            }
 
705
            else if (apoColumnTypes[i] == MDB_Binary ||
 
706
                     apoColumnTypes[i] == MDB_OLE)
 
707
            {
 
708
                int nBytes;
 
709
                GByte* pData = GetColumnAsBinary(i, &nBytes);
 
710
                printf("(%d bytes)\n", nBytes);
 
711
                CPLFree(pData);
 
712
            }
 
713
            else
 
714
            {
 
715
                char* val = GetColumnAsString(i);
 
716
                printf("'%s'\n", val);
 
717
                CPLFree(val);
 
718
            }
 
719
        }
 
720
    }
 
721
}
 
722
 
 
723
/************************************************************************/
 
724
/*                            GetColumnIndex()                          */
 
725
/************************************************************************/
 
726
 
 
727
int OGRMDBTable::GetColumnIndex(const char* pszColName, int bEmitErrorIfNotFound)
 
728
{
 
729
    int nCols = apoColumnNames.size();
 
730
    CPLString osColName(pszColName);
 
731
    for(int i=0;i<nCols;i++)
 
732
    {
 
733
        if (apoColumnNames[i] == osColName)
 
734
            return i;
 
735
    }
 
736
    if (bEmitErrorIfNotFound)
 
737
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot find column %s", pszColName);
 
738
    return -1;
 
739
}
 
740
 
 
741
/************************************************************************/
 
742
/*                             GetRowCount()                            */
 
743
/************************************************************************/
 
744
 
 
745
int OGRMDBTable::GetRowCount()
 
746
{
 
747
    if (env->bCalledFromJava)
 
748
        env->Init();
 
749
    int nRowCount = env->env->CallIntMethod(table, env->table_getRowCount);
 
750
    if (env->ExceptionOccured()) return 0;
 
751
    return nRowCount;
 
752
}