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