1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include "libzfs_jni_property.h"
26 #include "libzfs_jni_util.h"
27 #include <strings.h>
28
29 /*
30 * Types
31 */
32
33 /* Signature for function to convert string to a specific Java object */
34 typedef jobject (*str_to_obj_f)(JNIEnv *, char *);
35
36 /* Signature for function to convert uint64_t to a specific Java object */
37 typedef jobject (*uint64_to_obj_f)(JNIEnv *, uint64_t);
38
39 /*
40 * Describes a property and the parameters needed to create a Java
41 * Property object for it
42 */
43 typedef struct custom_prop_desct {
44 zfs_prop_t prop;
45 str_to_obj_f convert_str;
46 uint64_to_obj_f convert_uint64;
47 char *propClass;
48 char *valueClass;
49 } custom_prop_desct_t;
50
51 /*
52 * Function prototypes
53 */
54
55 static jobject create_BasicProperty(JNIEnv *, zfs_handle_t *,
56 zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *);
57 static jobject create_BooleanProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
58 static jobject create_LongProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
59 static jobject create_StringProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
60 static jobject create_ObjectProperty(JNIEnv *, zfs_handle_t *,
61 zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *);
62 static jobject create_default_BasicProperty(JNIEnv *, zfs_prop_t,
63 str_to_obj_f, uint64_to_obj_f, char *, char *);
64 static jobject create_default_BooleanProperty(JNIEnv *, zfs_prop_t);
65 static jobject create_default_LongProperty(JNIEnv *, zfs_prop_t);
66 static jobject create_default_StringProperty(JNIEnv *, zfs_prop_t);
67 static jobject create_default_ObjectProperty(
68 JNIEnv *, zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *);
69 static jobject str_to_enum_element(JNIEnv *, char *, char *);
70 static jobject str_to_aclinherit(JNIEnv *, char *);
71 static jobject str_to_checksum(JNIEnv *, char *);
72 static jobject str_to_compression(JNIEnv *, char *);
73 static jobject str_to_snapdir(JNIEnv *, char *);
74 static jobject str_to_string(JNIEnv *, char *);
75
76 /*
77 * Static data
78 */
79
80 zfs_prop_t props_boolean[] = {
81 ZFS_PROP_ATIME,
82 ZFS_PROP_DEVICES,
83 ZFS_PROP_EXEC,
84 ZFS_PROP_MOUNTED,
85 ZFS_PROP_READONLY,
86 ZFS_PROP_SETUID,
87 ZFS_PROP_ZONED,
88 ZFS_PROP_DEFER_DESTROY,
89 ZPROP_INVAL
90 };
91
92 zfs_prop_t props_long[] = {
93 ZFS_PROP_AVAILABLE,
94 ZFS_PROP_CREATETXG,
95 ZFS_PROP_QUOTA,
96 ZFS_PROP_REFERENCED,
97 ZFS_PROP_RESERVATION,
98 ZFS_PROP_USED,
99 ZFS_PROP_VOLSIZE,
100 ZFS_PROP_REFQUOTA,
101 ZFS_PROP_REFRESERVATION,
102 ZFS_PROP_USERREFS,
103 ZPROP_INVAL
104 };
105
106 zfs_prop_t props_string[] = {
107 ZFS_PROP_ORIGIN,
108 /* ZFS_PROP_TYPE, */
109 ZPROP_INVAL
110 };
111
112 custom_prop_desct_t props_custom[] = {
113 { ZFS_PROP_ACLINHERIT, str_to_aclinherit, NULL,
114 ZFSJNI_PACKAGE_DATA "AclInheritProperty",
115 ZFSJNI_PACKAGE_DATA "AclInheritProperty$AclInherit" },
116
117 { ZFS_PROP_CHECKSUM, str_to_checksum, NULL,
118 ZFSJNI_PACKAGE_DATA "ChecksumProperty",
119 ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum" },
120
121 { ZFS_PROP_COMPRESSION, str_to_compression, NULL,
122 ZFSJNI_PACKAGE_DATA "CompressionProperty",
123 ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression" },
124
125 { ZFS_PROP_COMPRESSRATIO, NULL, zjni_long_to_Long,
126 ZFSJNI_PACKAGE_DATA "CompressRatioProperty",
127 "java/lang/Long" },
128
129 { ZFS_PROP_CREATION, zjni_str_to_date, NULL,
130 ZFSJNI_PACKAGE_DATA "CreationProperty",
131 "java/util/Date" },
132
133 { ZFS_PROP_MOUNTPOINT, str_to_string, NULL,
134 ZFSJNI_PACKAGE_DATA "MountPointProperty",
135 "java/lang/String" },
136
137 { ZFS_PROP_RECORDSIZE, NULL, zjni_long_to_Long,
138 ZFSJNI_PACKAGE_DATA "RecordSizeProperty",
139 "java/lang/Long" },
140
141 { ZFS_PROP_SHARENFS, str_to_string, NULL,
142 ZFSJNI_PACKAGE_DATA "ShareNFSProperty",
143 "java/lang/String" },
144
145 { ZFS_PROP_SNAPDIR, str_to_snapdir, NULL,
146 ZFSJNI_PACKAGE_DATA "SnapDirProperty",
147 ZFSJNI_PACKAGE_DATA "SnapDirProperty$SnapDir" },
148
149 { ZFS_PROP_VOLBLOCKSIZE, NULL, zjni_long_to_Long,
150 ZFSJNI_PACKAGE_DATA "VolBlockSizeProperty",
151 "java/lang/Long" },
152
153 { ZPROP_INVAL, NULL, NULL, NULL, NULL },
154 };
155
156 /*
157 * Static functions
158 */
159
160 static jobject
create_BasicProperty(JNIEnv * env,zfs_handle_t * zhp,zfs_prop_t prop,str_to_obj_f convert_str,uint64_to_obj_f convert_uint64,char * propClass,char * valueClass)161 create_BasicProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop,
162 str_to_obj_f convert_str, uint64_to_obj_f convert_uint64,
163 char *propClass, char *valueClass)
164 {
165 jobject propertyObject = NULL;
166 char source[ZFS_MAXNAMELEN];
167 zprop_source_t srctype;
168 jobject propValue = NULL;
169
170 if (convert_str != NULL) {
171 char propbuf[ZFS_MAXPROPLEN];
172 int result = zfs_prop_get(zhp, prop, propbuf,
173 sizeof (propbuf), &srctype, source, sizeof (source), 1);
174
175 if (result == 0)
176 propValue = convert_str(env, propbuf);
177 } else {
178 uint64_t value;
179 int result = zfs_prop_get_numeric(
180 zhp, prop, &value, &srctype, source, sizeof (source));
181
182 if (result == 0)
183 propValue = convert_uint64(env, value);
184 }
185
186 if (propValue != NULL) {
187
188 jmethodID constructor;
189 char signature[1024];
190 jclass class = (*env)->FindClass(env, propClass);
191
192 jstring propName = (*env)->NewStringUTF(
193 env, zfs_prop_to_name(prop));
194
195 jboolean readOnly = zfs_prop_readonly(prop) ?
196 JNI_TRUE : JNI_FALSE;
197
198 if (srctype == ZPROP_SRC_INHERITED) {
199
200 jstring propSource = (*env)->NewStringUTF(env, source);
201
202 (void) snprintf(signature, sizeof (signature),
203 "(Ljava/lang/String;L%s;ZLjava/lang/String;)V",
204 valueClass);
205
206 constructor = (*env)->GetMethodID(
207 env, class, "<init>", signature);
208
209 propertyObject = (*env)->NewObject(
210 env, class, constructor, propName, propValue,
211 readOnly, propSource);
212 } else {
213 jobject lineage = zjni_int_to_Lineage(env, srctype);
214
215 (void) snprintf(signature, sizeof (signature),
216 "(Ljava/lang/String;L%s;ZL"
217 ZFSJNI_PACKAGE_DATA "Property$Lineage;)V",
218 valueClass);
219
220 constructor = (*env)->GetMethodID(
221 env, class, "<init>", signature);
222
223 propertyObject = (*env)->NewObject(
224 env, class, constructor, propName, propValue,
225 readOnly, lineage);
226 }
227 }
228
229 return (propertyObject);
230 }
231
232 static jobject
create_BooleanProperty(JNIEnv * env,zfs_handle_t * zhp,zfs_prop_t prop)233 create_BooleanProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
234 {
235 return (create_BasicProperty(env, zhp, prop, NULL, zjni_int_to_boolean,
236 ZFSJNI_PACKAGE_DATA "BooleanProperty", "java/lang/Boolean"));
237 }
238
239 static jobject
create_LongProperty(JNIEnv * env,zfs_handle_t * zhp,zfs_prop_t prop)240 create_LongProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
241 {
242 return (create_BasicProperty(env, zhp, prop, NULL, zjni_long_to_Long,
243 ZFSJNI_PACKAGE_DATA "LongProperty", "java/lang/Long"));
244 }
245
246 static jobject
create_StringProperty(JNIEnv * env,zfs_handle_t * zhp,zfs_prop_t prop)247 create_StringProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
248 {
249 return (create_BasicProperty(env, zhp, prop, str_to_string, NULL,
250 ZFSJNI_PACKAGE_DATA "StringProperty", "java/lang/String"));
251 }
252
253 static jobject
create_ObjectProperty(JNIEnv * env,zfs_handle_t * zhp,zfs_prop_t prop,str_to_obj_f convert_str,uint64_to_obj_f convert_uint64,char * propClass,char * valueClass)254 create_ObjectProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop,
255 str_to_obj_f convert_str, uint64_to_obj_f convert_uint64,
256 char *propClass, char *valueClass)
257 {
258 jobject propertyObject = NULL;
259 char source[ZFS_MAXNAMELEN];
260 zprop_source_t srctype;
261 jobject propValue = NULL;
262
263 if (convert_str != NULL) {
264 char propbuf[ZFS_MAXPROPLEN];
265 int result = zfs_prop_get(zhp, prop, propbuf,
266 sizeof (propbuf), &srctype, source, sizeof (source), 1);
267
268 if (result == 0)
269 propValue = convert_str(env, propbuf);
270 } else {
271 uint64_t value;
272 int result = zfs_prop_get_numeric(
273 zhp, prop, &value, &srctype, source, sizeof (source));
274
275 if (result == 0)
276 propValue = convert_uint64(env, value);
277 }
278
279 if (propValue != NULL) {
280
281 jmethodID constructor;
282 char signature[1024];
283 jclass class = (*env)->FindClass(env, propClass);
284
285 if (srctype == ZPROP_SRC_INHERITED) {
286
287 jstring propSource = (*env)->NewStringUTF(env, source);
288
289 (void) snprintf(signature, sizeof (signature),
290 "(L%s;Ljava/lang/String;)V", valueClass);
291
292 constructor = (*env)->GetMethodID(
293 env, class, "<init>", signature);
294
295 propertyObject = (*env)->NewObject(env,
296 class, constructor, propValue, propSource);
297
298 } else {
299 jobject lineage = zjni_int_to_Lineage(env, srctype);
300
301 (void) snprintf(signature, sizeof (signature),
302 "(L%s;L" ZFSJNI_PACKAGE_DATA "Property$Lineage;)V",
303 valueClass);
304
305 constructor = (*env)->GetMethodID(
306 env, class, "<init>", signature);
307
308 propertyObject = (*env)->NewObject(env,
309 class, constructor, propValue, lineage);
310 }
311 }
312
313 return (propertyObject);
314 }
315
316 static jobject
create_default_BasicProperty(JNIEnv * env,zfs_prop_t prop,str_to_obj_f convert_str,uint64_to_obj_f convert_uint64,char * propClass,char * valueClass)317 create_default_BasicProperty(JNIEnv *env, zfs_prop_t prop,
318 str_to_obj_f convert_str, uint64_to_obj_f convert_uint64,
319 char *propClass, char *valueClass)
320 {
321 jobject propertyObject = NULL;
322
323 if (!zfs_prop_readonly(prop)) {
324 jobject propValue;
325
326 if (convert_str != NULL) {
327 char *propbuf = (char *)zfs_prop_default_string(prop);
328 propValue = convert_str(env, propbuf);
329 } else {
330 uint64_t value = zfs_prop_default_numeric(prop);
331 propValue = convert_uint64(env, value);
332 }
333
334 if (propValue != NULL) {
335 char signature[1024];
336 jmethodID constructor;
337
338 jstring propName =
339 (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
340
341 jboolean readOnly = zfs_prop_readonly(prop) ?
342 JNI_TRUE : JNI_FALSE;
343
344 jclass class = (*env)->FindClass(env, propClass);
345 jobject lineage =
346 zjni_int_to_Lineage(env, ZPROP_SRC_DEFAULT);
347
348 (void) snprintf(signature, sizeof (signature),
349 "(Ljava/lang/String;L%s;ZL" ZFSJNI_PACKAGE_DATA
350 "Property$Lineage;)V", valueClass);
351
352 constructor = (*env)->GetMethodID(
353 env, class, "<init>", signature);
354
355 propertyObject = (*env)->NewObject(
356 env, class, constructor,
357 propName, propValue, readOnly, lineage);
358 }
359 }
360
361 return (propertyObject);
362 }
363
364 static jobject
create_default_BooleanProperty(JNIEnv * env,zfs_prop_t prop)365 create_default_BooleanProperty(JNIEnv *env, zfs_prop_t prop)
366 {
367 return (create_default_BasicProperty(env, prop, NULL,
368 zjni_int_to_boolean, ZFSJNI_PACKAGE_DATA "BooleanProperty",
369 "java/lang/Boolean"));
370 }
371
372 static jobject
create_default_LongProperty(JNIEnv * env,zfs_prop_t prop)373 create_default_LongProperty(JNIEnv *env, zfs_prop_t prop)
374 {
375 return (create_default_BasicProperty(env, prop, NULL,
376 zjni_long_to_Long, ZFSJNI_PACKAGE_DATA "LongProperty",
377 "java/lang/Long"));
378 }
379
380 static jobject
create_default_StringProperty(JNIEnv * env,zfs_prop_t prop)381 create_default_StringProperty(JNIEnv *env, zfs_prop_t prop)
382 {
383 return (create_default_BasicProperty(env, prop, str_to_string, NULL,
384 ZFSJNI_PACKAGE_DATA "StringProperty", "java/lang/String"));
385 }
386
387 static jobject
create_default_ObjectProperty(JNIEnv * env,zfs_prop_t prop,str_to_obj_f convert_str,uint64_to_obj_f convert_uint64,char * propClass,char * valueClass)388 create_default_ObjectProperty(JNIEnv *env, zfs_prop_t prop,
389 str_to_obj_f convert_str, uint64_to_obj_f convert_uint64,
390 char *propClass, char *valueClass)
391 {
392 jobject propertyObject = NULL;
393
394 if (!zfs_prop_readonly(prop)) {
395 jobject propValue;
396
397 if (convert_str != NULL) {
398 char *propbuf = (char *)zfs_prop_default_string(prop);
399 propValue = convert_str(env, propbuf);
400 } else {
401 uint64_t value = zfs_prop_default_numeric(prop);
402 propValue = convert_uint64(env, value);
403 }
404
405 if (propValue != NULL) {
406 char signature[1024];
407 jmethodID constructor;
408
409 jclass class = (*env)->FindClass(env, propClass);
410 jobject lineage =
411 zjni_int_to_Lineage(env, ZPROP_SRC_DEFAULT);
412
413 (void) snprintf(signature, sizeof (signature),
414 "(L%s;L" ZFSJNI_PACKAGE_DATA "Property$Lineage;)V",
415 valueClass);
416
417 constructor = (*env)->GetMethodID(
418 env, class, "<init>", signature);
419
420 propertyObject = (*env)->NewObject(
421 env, class, constructor, propValue, lineage);
422 }
423 }
424
425 return (propertyObject);
426 }
427
428 static jobject
str_to_enum_element(JNIEnv * env,char * str,char * valueClass)429 str_to_enum_element(JNIEnv *env, char *str, char *valueClass)
430 {
431 char signature[1024];
432 jmethodID method_valueOf;
433
434 jstring utf = (*env)->NewStringUTF(env, str);
435 jclass class = (*env)->FindClass(env, valueClass);
436
437 (void) snprintf(signature, sizeof (signature),
438 "(Ljava/lang/String;)L%s;", valueClass);
439
440 method_valueOf = (*env)->GetStaticMethodID(
441 env, class, "valueOf", signature);
442
443 return (*env)->CallStaticObjectMethod(env, class, method_valueOf, utf);
444 }
445
446 static jobject
str_to_aclinherit(JNIEnv * env,char * str)447 str_to_aclinherit(JNIEnv *env, char *str)
448 {
449 return (str_to_enum_element(env, str,
450 ZFSJNI_PACKAGE_DATA "AclInheritProperty$AclInherit"));
451 }
452
453 static jobject
str_to_checksum(JNIEnv * env,char * str)454 str_to_checksum(JNIEnv *env, char *str)
455 {
456 return (str_to_enum_element(env, str,
457 ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum"));
458 }
459
460 static jobject
str_to_compression(JNIEnv * env,char * str)461 str_to_compression(JNIEnv *env, char *str)
462 {
463 return (str_to_enum_element(env, str,
464 ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression"));
465 }
466
467 static jobject
str_to_snapdir(JNIEnv * env,char * str)468 str_to_snapdir(JNIEnv *env, char *str)
469 {
470 return (str_to_enum_element(env, str,
471 ZFSJNI_PACKAGE_DATA "SnapDirProperty$SnapDir"));
472 }
473
474 static jobject
str_to_string(JNIEnv * env,char * str)475 str_to_string(JNIEnv *env, char *str)
476 {
477 return (*env)->NewStringUTF(env, str);
478 }
479
480 /*
481 * Package-private functions
482 */
483
484 jobject
zjni_get_default_property(JNIEnv * env,zfs_prop_t prop)485 zjni_get_default_property(JNIEnv *env, zfs_prop_t prop)
486 {
487 int i;
488 for (i = 0; props_boolean[i] != ZPROP_INVAL; i++) {
489 if (prop == props_boolean[i]) {
490 return (create_default_BooleanProperty(env, prop));
491 }
492 }
493
494 for (i = 0; props_long[i] != ZPROP_INVAL; i++) {
495 if (prop == props_long[i]) {
496 return (create_default_LongProperty(env, prop));
497 }
498 }
499
500 for (i = 0; props_string[i] != ZPROP_INVAL; i++) {
501 if (prop == props_string[i]) {
502 return (create_default_StringProperty(env, prop));
503 }
504 }
505
506 for (i = 0; props_custom[i].prop != ZPROP_INVAL; i++) {
507 if (prop == props_custom[i].prop) {
508 return create_default_ObjectProperty(env,
509 props_custom[i].prop,
510 props_custom[i].convert_str,
511 props_custom[i].convert_uint64,
512 props_custom[i].propClass,
513 props_custom[i].valueClass);
514 }
515 }
516
517 return (NULL);
518 }
519
520 static int
zjni_get_property_from_name_cb(int prop,void * cb)521 zjni_get_property_from_name_cb(int prop, void *cb)
522 {
523 const char *name = cb;
524
525 if (strcasecmp(name, zfs_prop_to_name(prop)) == 0)
526 return (prop);
527
528 return (ZPROP_CONT);
529 }
530
531 zfs_prop_t
zjni_get_property_from_name(const char * name)532 zjni_get_property_from_name(const char *name)
533 {
534 zfs_prop_t prop;
535
536 prop = zprop_iter(zjni_get_property_from_name_cb, (void *)name,
537 B_FALSE, B_FALSE, ZFS_TYPE_DATASET);
538 return (prop == ZPROP_CONT ? ZPROP_INVAL : prop);
539 }
540
541 jobject
zjni_int_to_Lineage(JNIEnv * env,zprop_source_t srctype)542 zjni_int_to_Lineage(JNIEnv *env, zprop_source_t srctype)
543 {
544 /* zprop_source_t to Property$Lineage map */
545 static zjni_field_mapping_t lineage_map[] = {
546 { ZPROP_SRC_NONE, "ZFS_PROP_LINEAGE_NOTINHERITABLE" },
547 { ZPROP_SRC_DEFAULT, "ZFS_PROP_LINEAGE_DEFAULT" },
548 { ZPROP_SRC_LOCAL, "ZFS_PROP_LINEAGE_LOCAL" },
549 { ZPROP_SRC_TEMPORARY, "ZFS_PROP_LINEAGE_TEMPORARY" },
550 { ZPROP_SRC_INHERITED, "ZFS_PROP_LINEAGE_INHERITED" }
551 };
552
553 return (zjni_int_to_enum(env, srctype,
554 ZFSJNI_PACKAGE_DATA "Property$Lineage",
555 "ZFS_PROP_LINEAGE_INHERITED", lineage_map));
556 }
557
558 jobjectArray
zjni_get_Dataset_properties(JNIEnv * env,zfs_handle_t * zhp)559 zjni_get_Dataset_properties(JNIEnv *env, zfs_handle_t *zhp)
560 {
561 jobject prop;
562 int i;
563
564 /* Create an array list for the properties */
565 zjni_ArrayList_t proplist_obj = {0};
566 zjni_ArrayList_t *proplist = &proplist_obj;
567 zjni_new_ArrayList(env, proplist);
568
569 for (i = 0; props_boolean[i] != ZPROP_INVAL; i++) {
570 /* Create property and add to list */
571 prop = create_BooleanProperty(env, zhp, props_boolean[i]);
572
573 /* Does this property apply to this object? */
574 if (prop != NULL) {
575
576 (*env)->CallBooleanMethod(
577 env, ((zjni_Object_t *)proplist)->object,
578 ((zjni_Collection_t *)proplist)->method_add, prop);
579 } else {
580
581 if ((*env)->ExceptionOccurred(env) != NULL) {
582 return (NULL);
583 }
584 #ifdef DEBUG
585 (void) fprintf(stderr, "Property %s is not appropriate "
586 "for %s\n", zfs_prop_to_name(props_boolean[i]),
587 zfs_get_name(zhp));
588 #endif
589 }
590 }
591
592 for (i = 0; props_long[i] != ZPROP_INVAL; i++) {
593 /* Create property and add to list */
594 prop = create_LongProperty(env, zhp, props_long[i]);
595
596 /* Does this property apply to this object? */
597 if (prop != NULL) {
598
599 (*env)->CallBooleanMethod(
600 env, ((zjni_Object_t *)proplist)->object,
601 ((zjni_Collection_t *)proplist)->method_add, prop);
602 } else {
603 if ((*env)->ExceptionOccurred(env) != NULL) {
604 return (NULL);
605 }
606 #ifdef DEBUG
607 (void) fprintf(stderr, "Property %s is not appropriate "
608 "for %s\n", zfs_prop_to_name(props_long[i]),
609 zfs_get_name(zhp));
610 #endif
611 }
612 }
613
614 for (i = 0; props_string[i] != ZPROP_INVAL; i++) {
615 /* Create property and add to list */
616 prop = create_StringProperty(env, zhp, props_string[i]);
617
618 /* Does this property apply to this object? */
619 if (prop != NULL) {
620
621 (*env)->CallBooleanMethod(
622 env, ((zjni_Object_t *)proplist)->object,
623 ((zjni_Collection_t *)proplist)->method_add, prop);
624 } else {
625 if ((*env)->ExceptionOccurred(env) != NULL) {
626 return (NULL);
627 }
628 #ifdef DEBUG
629 (void) fprintf(stderr, "Property %s is not appropriate "
630 "for %s\n", zfs_prop_to_name(props_string[i]),
631 zfs_get_name(zhp));
632 #endif
633 }
634 }
635
636 for (i = 0; props_custom[i].prop != ZPROP_INVAL; i++) {
637 /* Create property and add to list */
638 prop = create_ObjectProperty(env, zhp, props_custom[i].prop,
639 props_custom[i].convert_str, props_custom[i].convert_uint64,
640 props_custom[i].propClass, props_custom[i].valueClass);
641
642 /* Does this property apply to this object? */
643 if (prop != NULL) {
644
645 (*env)->CallBooleanMethod(
646 env, ((zjni_Object_t *)proplist)->object,
647 ((zjni_Collection_t *)proplist)->method_add, prop);
648 } else {
649 if ((*env)->ExceptionOccurred(env) != NULL) {
650 return (NULL);
651 }
652 #ifdef DEBUG
653 (void) fprintf(stderr, "Property %s is not appropriate "
654 "for %s\n", zfs_prop_to_name(props_custom[i].prop),
655 zfs_get_name(zhp));
656 #endif
657 }
658 }
659
660 return (zjni_Collection_to_array(env,
661 (zjni_Collection_t *)proplist, ZFSJNI_PACKAGE_DATA "Property"));
662 }
663