xref: /illumos-gate/usr/src/lib/libzfs_jni/common/libzfs_jni_property.c (revision 4de2612967d06c4fdbf524a62556a1e8118a006f)
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  * Function prototypes
35  */
36 
37 static jobject create_BooleanProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
38 static jobject create_ChecksumProperty(JNIEnv *, zfs_handle_t *);
39 static jobject create_CompressionProperty(JNIEnv *, zfs_handle_t *);
40 static jobject create_DateProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
41 static jobject create_LongProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
42 static jobject create_RecordSizeProperty(JNIEnv *, zfs_handle_t *);
43 static jobject create_StringProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
44 static jobject str_to_checksum(JNIEnv *, char *);
45 static jobject str_to_compression(JNIEnv *, char *);
46 static jobject create_default_BooleanProperty(JNIEnv *, zfs_prop_t);
47 static jobject create_default_LongProperty(JNIEnv *, zfs_prop_t);
48 static jobject create_default_StringProperty(JNIEnv *, zfs_prop_t);
49 static jobject create_default_MountPointProperty(JNIEnv *);
50 static jobject create_default_ShareNFSProperty(JNIEnv *);
51 static jobject create_default_ChecksumProperty(JNIEnv *);
52 static jobject create_default_CompressionProperty(JNIEnv *);
53 static jobject create_default_RecordSizeProperty(JNIEnv *);
54 
55 /*
56  * Static data
57  */
58 
59 zfs_prop_t props_boolean[] = {
60 	ZFS_PROP_ATIME,
61 	ZFS_PROP_DEVICES,
62 	ZFS_PROP_EXEC,
63 	ZFS_PROP_MOUNTED,
64 	ZFS_PROP_READONLY,
65 	ZFS_PROP_SETUID,
66 	ZFS_PROP_ZONED,
67 	ZFS_PROP_INVAL
68 };
69 
70 zfs_prop_t props_long[] = {
71 	ZFS_PROP_AVAILABLE,
72 	ZFS_PROP_QUOTA,
73 	/*	ZFS_PROP_RATIO, */
74 	ZFS_PROP_REFERENCED,
75 	ZFS_PROP_RESERVATION,
76 	ZFS_PROP_USED,
77 	ZFS_PROP_VOLSIZE,
78 	ZFS_PROP_INVAL
79 };
80 
81 zfs_prop_t props_string[] = {
82 	ZFS_PROP_ORIGIN,
83 	/*	ZFS_PROP_TYPE, */
84 	ZFS_PROP_INVAL
85 };
86 
87 /*
88  * Static functions
89  */
90 
91 static jobject
92 create_BooleanProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
93 {
94 	jobject propertyObject = NULL;
95 	char source[ZFS_MAXNAMELEN];
96 	uint64_t value;
97 	zfs_source_t srctype;
98 
99 	int result = zfs_prop_get_numeric(zhp, prop, &value,
100 	    &srctype, source, sizeof (source));
101 
102 	if (result == 0) {
103 		jclass class_BooleanProperty = (*env)->FindClass(env,
104 		    ZFSJNI_PACKAGE_DATA "BooleanProperty");
105 
106 		jstring propName = (*env)->NewStringUTF(
107 		    env, zfs_prop_to_name(prop));
108 		jobject propValue = zjni_int_to_boolean(env, value);
109 		jboolean readOnly = zfs_prop_readonly(prop) ?
110 		    JNI_TRUE : JNI_FALSE;
111 
112 		jmethodID constructor_BooleanProperty;
113 
114 		if (srctype == ZFS_SRC_INHERITED) {
115 
116 			jstring propSource = (*env)->NewStringUTF(env, source);
117 			constructor_BooleanProperty = (*env)->GetMethodID(
118 			    env, class_BooleanProperty, "<init>",
119 			    "(Ljava/lang/String;Ljava/lang/Boolean;ZL"
120 			    "java/lang/String;)V");
121 
122 			propertyObject = (*env)->NewObject(
123 			    env, class_BooleanProperty,
124 			    constructor_BooleanProperty,
125 			    propName, propValue, readOnly, propSource);
126 		} else {
127 			jobject lineage = zjni_get_lineage(env, srctype);
128 
129 			constructor_BooleanProperty = (*env)->GetMethodID(
130 			    env, class_BooleanProperty, "<init>",
131 			    "(Ljava/lang/String;Ljava/lang/Boolean;ZL"
132 			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
133 
134 			propertyObject = (*env)->NewObject(
135 			    env, class_BooleanProperty,
136 			    constructor_BooleanProperty,
137 			    propName, propValue, readOnly, lineage);
138 		}
139 	}
140 
141 	return (propertyObject);
142 }
143 
144 static jobject
145 create_ChecksumProperty(JNIEnv *env, zfs_handle_t *zhp)
146 {
147 	jobject propertyObject = NULL;
148 	char propbuf[ZFS_MAXPROPLEN];
149 	char source[ZFS_MAXNAMELEN];
150 	zfs_source_t srctype;
151 
152 	int result = zfs_prop_get(zhp, ZFS_PROP_CHECKSUM,
153 	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
154 
155 	if (result == 0) {
156 		jobject propValue = str_to_checksum(env, propbuf);
157 
158 		if (propValue != NULL) {
159 
160 			jclass class_ChecksumProperty = (*env)->FindClass(env,
161 			    ZFSJNI_PACKAGE_DATA "ChecksumProperty");
162 
163 			jmethodID constructor_ChecksumProperty;
164 
165 			if (srctype == ZFS_SRC_INHERITED) {
166 
167 				jstring propSource = (*env)->NewStringUTF(env,
168 				    source);
169 				constructor_ChecksumProperty =
170 				    (*env)->GetMethodID(
171 					env, class_ChecksumProperty, "<init>",
172 					"(L" ZFSJNI_PACKAGE_DATA
173 					"ChecksumProperty$Checksum;Ljava/lang/"
174 					"String;)V");
175 
176 				propertyObject = (*env)->NewObject(env,
177 				    class_ChecksumProperty,
178 				    constructor_ChecksumProperty,
179 				    propValue, propSource);
180 
181 			} else {
182 				jobject lineage =
183 				    zjni_get_lineage(env, srctype);
184 				constructor_ChecksumProperty =
185 				    (*env)->GetMethodID(
186 					env, class_ChecksumProperty, "<init>",
187 					"(L" ZFSJNI_PACKAGE_DATA
188 					"ChecksumProperty$Checksum;L"
189 					ZFSJNI_PACKAGE_DATA
190 					"Property$Lineage;)V");
191 
192 				propertyObject = (*env)->NewObject(env,
193 				    class_ChecksumProperty,
194 				    constructor_ChecksumProperty,
195 				    propValue, lineage);
196 			}
197 		}
198 	}
199 
200 	return (propertyObject);
201 }
202 
203 static jobject
204 create_CompressionProperty(JNIEnv *env, zfs_handle_t *zhp)
205 {
206 	jobject propertyObject = NULL;
207 	char propbuf[ZFS_MAXPROPLEN];
208 	char source[ZFS_MAXNAMELEN];
209 	zfs_source_t srctype;
210 
211 	int result = zfs_prop_get(zhp, ZFS_PROP_COMPRESSION,
212 	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
213 
214 	if (result == 0) {
215 		jobject propValue = str_to_compression(env, propbuf);
216 
217 		if (propValue != NULL) {
218 
219 			jclass class_CompressionProperty =
220 			    (*env)->FindClass(env,
221 				ZFSJNI_PACKAGE_DATA "CompressionProperty");
222 
223 			jmethodID constructor_CompressionProperty;
224 
225 			if (srctype == ZFS_SRC_INHERITED) {
226 
227 				jstring propSource = (*env)->NewStringUTF(env,
228 				    source);
229 				constructor_CompressionProperty =
230 				    (*env)->GetMethodID(
231 					env, class_CompressionProperty,
232 					"<init>",
233 					"(L" ZFSJNI_PACKAGE_DATA
234 					"CompressionProperty$Compression;Ljava/"
235 					"lang/String;)V");
236 
237 				propertyObject = (*env)->NewObject(env,
238 				    class_CompressionProperty,
239 				    constructor_CompressionProperty,
240 				    propValue, propSource);
241 			} else {
242 				jobject lineage = zjni_get_lineage(env,
243 				    srctype);
244 
245 				constructor_CompressionProperty =
246 				    (*env)->GetMethodID(
247 					env, class_CompressionProperty,
248 					"<init>",
249 					"(L" ZFSJNI_PACKAGE_DATA
250 					"CompressionProperty$Compression;L"
251 					ZFSJNI_PACKAGE_DATA
252 					"Property$Lineage;)V");
253 
254 				propertyObject = (*env)->NewObject(env,
255 				    class_CompressionProperty,
256 				    constructor_CompressionProperty,
257 				    propValue, lineage);
258 			}
259 		}
260 	}
261 
262 	return (propertyObject);
263 }
264 
265 static jobject
266 create_DateProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
267 {
268 	jobject propertyObject = NULL;
269 	char propbuf[ZFS_MAXPROPLEN];
270 	char source[ZFS_MAXNAMELEN];
271 	zfs_source_t srctype;
272 
273 	int result = zfs_prop_get(zhp, prop, propbuf, sizeof (propbuf),
274 	    &srctype, source, sizeof (source), 1);
275 
276 	if (result == 0) {
277 
278 		jobject propValue = zjni_str_to_date(env, propbuf);
279 		if (propValue != NULL) {
280 
281 			jclass class_DateProperty = (*env)->FindClass(env,
282 			    ZFSJNI_PACKAGE_DATA "DateProperty");
283 
284 			jstring propName = (*env)->NewStringUTF(
285 			    env, zfs_prop_to_name(prop));
286 			jboolean readOnly =
287 			    zfs_prop_readonly(prop) ? JNI_TRUE : JNI_FALSE;
288 
289 			jmethodID constructor_DateProperty;
290 
291 			if (srctype == ZFS_SRC_INHERITED) {
292 
293 				jstring propSource = (*env)->NewStringUTF(env,
294 				    source);
295 				constructor_DateProperty = (*env)->GetMethodID(
296 				    env, class_DateProperty, "<init>",
297 				    "(Ljava/lang/String;Ljava/util/Date;ZL"
298 				    "java/lang/String;)V");
299 
300 				propertyObject = (*env)->NewObject(
301 				    env, class_DateProperty,
302 				    constructor_DateProperty,
303 				    propName, propValue, readOnly, propSource);
304 			} else {
305 				jobject lineage = zjni_get_lineage(env,
306 				    srctype);
307 
308 				constructor_DateProperty = (*env)->GetMethodID(
309 				    env, class_DateProperty, "<init>",
310 				    "(Ljava/lang/String;Ljava/util/Date;ZL"
311 				    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
312 
313 				propertyObject = (*env)->NewObject(
314 				    env, class_DateProperty,
315 				    constructor_DateProperty,
316 				    propName, propValue, readOnly, lineage);
317 			}
318 		}
319 	}
320 
321 	return (propertyObject);
322 }
323 
324 static jobject
325 create_LongProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
326 {
327 	jobject propertyObject = NULL;
328 	char propbuf[ZFS_MAXPROPLEN];
329 	char source[ZFS_MAXNAMELEN];
330 	zfs_source_t srctype;
331 
332 	int result = zfs_prop_get(zhp, prop, propbuf, sizeof (propbuf),
333 	    &srctype, source, sizeof (source), 1);
334 
335 	if (result == 0) {
336 
337 		jobject propValue = zjni_str_to_long(env, propbuf);
338 		if (propValue != NULL) {
339 
340 			jclass class_LongProperty = (*env)->FindClass(env,
341 			    ZFSJNI_PACKAGE_DATA "LongProperty");
342 
343 			jstring propName = (*env)->NewStringUTF(
344 			    env, zfs_prop_to_name(prop));
345 			jboolean readOnly =
346 			    zfs_prop_readonly(prop) ? JNI_TRUE : JNI_FALSE;
347 
348 			jmethodID constructor_LongProperty;
349 
350 			if (srctype == ZFS_SRC_INHERITED) {
351 
352 				jstring propSource =
353 				    (*env)->NewStringUTF(env, source);
354 				constructor_LongProperty = (*env)->GetMethodID(
355 				    env, class_LongProperty, "<init>",
356 				    "(Ljava/lang/String;Ljava/lang/Long;ZL"
357 				    "java/lang/String;)V");
358 
359 				propertyObject = (*env)->NewObject(
360 				    env, class_LongProperty,
361 				    constructor_LongProperty,
362 				    propName, propValue, readOnly, propSource);
363 			} else {
364 				jobject lineage = zjni_get_lineage(env,
365 				    srctype);
366 
367 				constructor_LongProperty = (*env)->GetMethodID(
368 				    env, class_LongProperty, "<init>",
369 				    "(Ljava/lang/String;Ljava/lang/Long;ZL"
370 				    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
371 
372 				propertyObject = (*env)->NewObject(
373 				    env, class_LongProperty,
374 				    constructor_LongProperty,
375 				    propName, propValue, readOnly, lineage);
376 			}
377 		}
378 	}
379 
380 	return (propertyObject);
381 }
382 
383 static jobject
384 create_RecordSizeProperty(JNIEnv *env, zfs_handle_t *zhp)
385 {
386 	jobject propertyObject = NULL;
387 	char propbuf[ZFS_MAXPROPLEN];
388 	char source[ZFS_MAXNAMELEN];
389 	zfs_source_t srctype;
390 
391 	int result = zfs_prop_get(zhp, ZFS_PROP_RECORDSIZE,
392 	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
393 
394 	if (result == 0) {
395 
396 		jobject propValue = zjni_str_to_long(env, propbuf);
397 		if (propValue != NULL) {
398 
399 			jclass class_RecordSizeProperty = (*env)->FindClass(env,
400 			    ZFSJNI_PACKAGE_DATA "RecordSizeProperty");
401 
402 			jmethodID constructor_RecordSizeProperty;
403 
404 			if (srctype == ZFS_SRC_INHERITED) {
405 
406 				jstring propSource =
407 				    (*env)->NewStringUTF(env, source);
408 				constructor_RecordSizeProperty =
409 				    (*env)->GetMethodID(
410 					env, class_RecordSizeProperty, "<init>",
411 					"(Ljava/lang/Long;Ljava/lang/"
412 					"String;)V");
413 
414 				propertyObject = (*env)->NewObject(env,
415 				    class_RecordSizeProperty,
416 				    constructor_RecordSizeProperty,
417 				    propValue, propSource);
418 			} else {
419 				jobject lineage =
420 				    zjni_get_lineage(env, srctype);
421 
422 				constructor_RecordSizeProperty =
423 				    (*env)->GetMethodID(
424 					env, class_RecordSizeProperty, "<init>",
425 					"(Ljava/lang/Long;L"
426 					ZFSJNI_PACKAGE_DATA
427 					"Property$Lineage;)V");
428 
429 				propertyObject = (*env)->NewObject(env,
430 				    class_RecordSizeProperty,
431 				    constructor_RecordSizeProperty,
432 				    propValue, lineage);
433 			}
434 		}
435 	}
436 
437 	return (propertyObject);
438 }
439 
440 static jobject
441 create_StringProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
442 {
443 	jobject propertyObject = NULL;
444 	char propbuf[ZFS_MAXPROPLEN];
445 	char source[ZFS_MAXNAMELEN];
446 	zfs_source_t srctype;
447 
448 	int result = zfs_prop_get(zhp, prop, propbuf, sizeof (propbuf),
449 	    &srctype, source, sizeof (source), 1);
450 
451 	if (result == 0) {
452 		jmethodID constructor_StringProperty;
453 
454 		jclass class_StringProperty =
455 		    (*env)->FindClass(env, ZFSJNI_PACKAGE_DATA
456 			"StringProperty");
457 
458 		jstring propName =
459 		    (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
460 
461 		jobject propValue = (*env)->NewStringUTF(env, propbuf);
462 		jboolean readOnly = zfs_prop_readonly(prop) ?
463 		    JNI_TRUE : JNI_FALSE;
464 
465 		if (srctype == ZFS_SRC_INHERITED) {
466 
467 			jstring propSource = (*env)->NewStringUTF(env, source);
468 			constructor_StringProperty = (*env)->GetMethodID(
469 			    env, class_StringProperty, "<init>",
470 			    "(Ljava/lang/String;Ljava/lang/String;ZL"
471 			    "java/lang/String;)V");
472 
473 			propertyObject = (*env)->NewObject(
474 			    env, class_StringProperty,
475 			    constructor_StringProperty,
476 			    propName, propValue, readOnly, propSource);
477 		} else {
478 			jobject lineage = zjni_get_lineage(env, srctype);
479 
480 			constructor_StringProperty = (*env)->GetMethodID(
481 			    env, class_StringProperty, "<init>",
482 			    "(Ljava/lang/String;Ljava/lang/String;ZL"
483 			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
484 
485 			propertyObject = (*env)->NewObject(
486 			    env, class_StringProperty,
487 			    constructor_StringProperty,
488 			    propName, propValue, readOnly, lineage);
489 		}
490 	}
491 
492 	return (propertyObject);
493 }
494 
495 static jobject
496 create_MountPointProperty(JNIEnv *env, zfs_handle_t *zhp)
497 {
498 	jobject propertyObject = NULL;
499 	char propbuf[ZFS_MAXPROPLEN];
500 	char source[ZFS_MAXNAMELEN];
501 	zfs_source_t srctype;
502 
503 	int result = zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT,
504 	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
505 
506 	if (result == 0) {
507 		jmethodID constructor_MountPointProperty;
508 
509 		jclass class_MountPointProperty = (*env)->FindClass(
510 		    env, ZFSJNI_PACKAGE_DATA "MountPointProperty");
511 
512 		jobject propValue = (*env)->NewStringUTF(env, propbuf);
513 
514 		if (srctype == ZFS_SRC_INHERITED) {
515 
516 			jstring propSource = (*env)->NewStringUTF(env, source);
517 			constructor_MountPointProperty = (*env)->GetMethodID(
518 			    env, class_MountPointProperty, "<init>",
519 			    "(Ljava/lang/String;Ljava/lang/String;)V");
520 
521 			propertyObject = (*env)->NewObject(env,
522 			    class_MountPointProperty,
523 			    constructor_MountPointProperty,
524 			    propValue, propSource);
525 		} else {
526 			jobject lineage = zjni_get_lineage(env, srctype);
527 
528 			constructor_MountPointProperty = (*env)->GetMethodID(
529 			    env, class_MountPointProperty, "<init>",
530 			    "(Ljava/lang/String;L"
531 			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
532 
533 			propertyObject = (*env)->NewObject(env,
534 			    class_MountPointProperty,
535 			    constructor_MountPointProperty,
536 			    propValue, lineage);
537 		}
538 	}
539 
540 	return (propertyObject);
541 }
542 
543 static jobject
544 create_ShareNFSProperty(JNIEnv *env, zfs_handle_t *zhp)
545 {
546 	jobject propertyObject = NULL;
547 	char propbuf[ZFS_MAXPROPLEN];
548 	char source[ZFS_MAXNAMELEN];
549 	zfs_source_t srctype;
550 
551 	int result = zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
552 	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
553 
554 	if (result == 0) {
555 		jmethodID constructor_ShareNFSProperty;
556 
557 		jclass class_ShareNFSProperty = (*env)->FindClass(
558 		    env, ZFSJNI_PACKAGE_DATA "ShareNFSProperty");
559 
560 		jobject propValue = (*env)->NewStringUTF(env, propbuf);
561 
562 		if (srctype == ZFS_SRC_INHERITED) {
563 
564 			jstring propSource = (*env)->NewStringUTF(env, source);
565 			constructor_ShareNFSProperty = (*env)->GetMethodID(
566 			    env, class_ShareNFSProperty, "<init>",
567 			    "(Ljava/lang/String;Ljava/lang/String;)V");
568 
569 			propertyObject = (*env)->NewObject(
570 			    env, class_ShareNFSProperty,
571 			    constructor_ShareNFSProperty,
572 			    propValue, propSource);
573 		} else {
574 			jobject lineage = zjni_get_lineage(env, srctype);
575 
576 			constructor_ShareNFSProperty = (*env)->GetMethodID(
577 			    env, class_ShareNFSProperty, "<init>",
578 			    "(Ljava/lang/String;L"
579 			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
580 
581 			propertyObject = (*env)->NewObject(
582 			    env, class_ShareNFSProperty,
583 			    constructor_ShareNFSProperty,
584 			    propValue, lineage);
585 		}
586 	}
587 
588 	return (propertyObject);
589 }
590 
591 static jobject
592 str_to_checksum(JNIEnv *env, char *str)
593 {
594 	jclass class_Checksum = (*env)->FindClass(
595 	    env, ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum");
596 
597 	jmethodID method_valueOf = (*env)->GetStaticMethodID(
598 	    env, class_Checksum, "valueOf",
599 	    "(Ljava/lang/String;)L"
600 	    ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum;");
601 
602 	jstring utf = (*env)->NewStringUTF(env, str);
603 
604 	return (*env)->CallStaticObjectMethod(
605 	    env, class_Checksum, method_valueOf, utf);
606 }
607 
608 static jobject
609 str_to_compression(JNIEnv *env, char *str)
610 {
611 	jclass class_Compression = (*env)->FindClass(
612 	    env, ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression");
613 
614 	jmethodID method_valueOf = (*env)->GetStaticMethodID(
615 	    env, class_Compression, "valueOf",
616 	    "(Ljava/lang/String;)L"
617 	    ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression;");
618 
619 	jstring utf = (*env)->NewStringUTF(env, str);
620 
621 	return (*env)->CallStaticObjectMethod(
622 	    env, class_Compression, method_valueOf, utf);
623 }
624 
625 /*
626  * Package-private functions
627  */
628 jobject
629 zjni_get_default_property(JNIEnv *env, zfs_prop_t prop)
630 {
631 	int i;
632 	for (i = 0; props_boolean[i] != ZFS_PROP_INVAL; i++) {
633 		if (prop == props_boolean[i]) {
634 			return (create_default_BooleanProperty(env, prop));
635 		}
636 	}
637 
638 	for (i = 0; props_long[i] != ZFS_PROP_INVAL; i++) {
639 		if (prop == props_long[i]) {
640 			return (create_default_LongProperty(env, prop));
641 		}
642 	}
643 
644 	for (i = 0; props_string[i] != ZFS_PROP_INVAL; i++) {
645 		if (prop == props_string[i]) {
646 			return (create_default_StringProperty(env, prop));
647 		}
648 	}
649 
650 	if (prop == ZFS_PROP_MOUNTPOINT) {
651 		return (create_default_MountPointProperty(env));
652 	}
653 
654 	if (prop == ZFS_PROP_SHARENFS) {
655 		return (create_default_ShareNFSProperty(env));
656 	}
657 
658 	if (prop == ZFS_PROP_CHECKSUM) {
659 		return (create_default_ChecksumProperty(env));
660 	}
661 
662 	if (prop == ZFS_PROP_COMPRESSION) {
663 		return (create_default_CompressionProperty(env));
664 	}
665 
666 	if (prop == ZFS_PROP_RECORDSIZE) {
667 		return (create_default_RecordSizeProperty(env));
668 	}
669 
670 	return (NULL);
671 }
672 
673 zfs_prop_t
674 zjni_get_property_from_name(const char *name)
675 {
676 	zfs_prop_t prop;
677 	for (prop = 0; prop < ZFS_NPROP_VISIBLE; prop++) {
678 		if (strcasecmp(name, zfs_prop_to_name(prop)) == 0) {
679 			return (prop);
680 		}
681 	}
682 
683 	return (ZFS_PROP_INVAL);
684 }
685 
686 jobject
687 zjni_get_lineage(JNIEnv *env, zfs_source_t srctype)
688 {
689 	char *field;
690 	jclass class_Lineage;
691 	jfieldID id;
692 
693 	switch (srctype) {
694 	case ZFS_SRC_NONE:
695 		field = "ZFS_PROP_LINEAGE_NOTINHERITABLE";
696 		break;
697 
698 	case ZFS_SRC_DEFAULT:
699 		field = "ZFS_PROP_LINEAGE_DEFAULT";
700 		break;
701 
702 	case ZFS_SRC_LOCAL:
703 		field = "ZFS_PROP_LINEAGE_LOCAL";
704 		break;
705 
706 	case ZFS_SRC_TEMPORARY:
707 		field = "ZFS_PROP_LINEAGE_TEMPORARY";
708 		break;
709 
710 	default:
711 	case ZFS_SRC_INHERITED:
712 		field = "ZFS_PROP_LINEAGE_INHERITED";
713 		break;
714 	}
715 
716 	class_Lineage = (*env)->FindClass(
717 	    env, ZFSJNI_PACKAGE_DATA "Property$Lineage");
718 
719 	id = (*env)->GetStaticFieldID(env, class_Lineage,
720 	    field, "L" ZFSJNI_PACKAGE_DATA "Property$Lineage;");
721 
722 	return (*env)->GetStaticObjectField(env, class_Lineage, id);
723 }
724 
725 jobjectArray
726 zjni_get_Dataset_properties(JNIEnv *env, zfs_handle_t *zhp)
727 {
728 	jobject prop;
729 	int i;
730 
731 	/* Create an array list for the properties */
732 	zjni_ArrayList_t proplist_obj = {0};
733 	zjni_ArrayList_t *proplist = &proplist_obj;
734 	zjni_new_ArrayList(env, proplist);
735 
736 	for (i = 0; props_boolean[i] != ZFS_PROP_INVAL; i++) {
737 		/* Create property and add to list */
738 		prop = create_BooleanProperty(env, zhp, props_boolean[i]);
739 
740 		/* Does this property apply to this object? */
741 		if (prop != NULL) {
742 
743 			(*env)->CallBooleanMethod(
744 			    env, ((zjni_Object_t *)proplist)->object,
745 			    ((zjni_Collection_t *)proplist)->method_add, prop);
746 		} else {
747 
748 			if ((*env)->ExceptionOccurred(env) != NULL) {
749 				return (NULL);
750 			}
751 #ifdef	DEBUG
752 			(void) fprintf(stderr, "Property %s is not appropriate "
753 			    "for %s\n", zfs_prop_to_name(props_boolean[i]),
754 			    zfs_get_name(zhp));
755 #endif
756 		}
757 	}
758 
759 	for (i = 0; props_long[i] != ZFS_PROP_INVAL; i++) {
760 		/* Create property and add to list */
761 		prop = create_LongProperty(env, zhp, props_long[i]);
762 
763 		/* Does this property apply to this object? */
764 		if (prop != NULL) {
765 
766 			(*env)->CallBooleanMethod(
767 			    env, ((zjni_Object_t *)proplist)->object,
768 			    ((zjni_Collection_t *)proplist)->method_add, prop);
769 		} else {
770 			if ((*env)->ExceptionOccurred(env) != NULL) {
771 				return (NULL);
772 			}
773 #ifdef	DEBUG
774 			(void) fprintf(stderr, "Property %s is not appropriate "
775 			    "for %s\n", zfs_prop_to_name(props_long[i]),
776 			    zfs_get_name(zhp));
777 #endif
778 		}
779 	}
780 
781 	for (i = 0; props_string[i] != ZFS_PROP_INVAL; i++) {
782 		/* Create property and add to list */
783 		prop = create_StringProperty(env, zhp, props_string[i]);
784 
785 		/* Does this property apply to this object? */
786 		if (prop != NULL) {
787 
788 			(*env)->CallBooleanMethod(
789 			    env, ((zjni_Object_t *)proplist)->object,
790 			    ((zjni_Collection_t *)proplist)->method_add, prop);
791 		} else {
792 			if ((*env)->ExceptionOccurred(env) != NULL) {
793 				return (NULL);
794 			}
795 #ifdef	DEBUG
796 			(void) fprintf(stderr, "Property %s is not appropriate "
797 			    "for %s\n", zfs_prop_to_name(props_string[i]),
798 			    zfs_get_name(zhp));
799 #endif
800 		}
801 	}
802 
803 	prop = create_MountPointProperty(env, zhp);
804 	/* Does this property apply to this object? */
805 	if (prop != NULL) {
806 
807 		(*env)->CallBooleanMethod(env,
808 		    ((zjni_Object_t *)proplist)->object,
809 		    ((zjni_Collection_t *)proplist)->method_add, prop);
810 	} else {
811 		if ((*env)->ExceptionOccurred(env) != NULL) {
812 			return (NULL);
813 		}
814 #ifdef	DEBUG
815 		(void) fprintf(stderr, "Property %s is not appropriate "
816 		    "for %s\n", zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
817 		    zfs_get_name(zhp));
818 #endif
819 	}
820 
821 	prop = create_ShareNFSProperty(env, zhp);
822 	/* Does this property apply to this object? */
823 	if (prop != NULL) {
824 
825 		(*env)->CallBooleanMethod(env,
826 		    ((zjni_Object_t *)proplist)->object,
827 		    ((zjni_Collection_t *)proplist)->method_add, prop);
828 	} else {
829 		if ((*env)->ExceptionOccurred(env) != NULL) {
830 			return (NULL);
831 		}
832 #ifdef	DEBUG
833 		(void) fprintf(stderr, "Property %s is not appropriate "
834 		    "for %s\n", zfs_prop_to_name(ZFS_PROP_SHARENFS),
835 		    zfs_get_name(zhp));
836 #endif
837 	}
838 
839 	prop = create_ChecksumProperty(env, zhp);
840 	/* Does this property apply to this object? */
841 	if (prop != NULL) {
842 
843 		(*env)->CallBooleanMethod(env,
844 		    ((zjni_Object_t *)proplist)->object,
845 		    ((zjni_Collection_t *)proplist)->method_add, prop);
846 	} else {
847 		if ((*env)->ExceptionOccurred(env) != NULL) {
848 			return (NULL);
849 		}
850 #ifdef	DEBUG
851 		(void) fprintf(stderr, "Property %s is not appropriate "
852 		    "for %s\n", zfs_prop_to_name(ZFS_PROP_CHECKSUM),
853 		    zfs_get_name(zhp));
854 #endif
855 	}
856 
857 	prop = create_CompressionProperty(env, zhp);
858 	/* Does this property apply to this object? */
859 	if (prop != NULL) {
860 
861 		(*env)->CallBooleanMethod(env,
862 		    ((zjni_Object_t *)proplist)->object,
863 		    ((zjni_Collection_t *)proplist)->method_add, prop);
864 	} else {
865 		if ((*env)->ExceptionOccurred(env) != NULL) {
866 			return (NULL);
867 		}
868 #ifdef	DEBUG
869 		(void) fprintf(stderr, "Property %s is not appropriate "
870 		    "for %s\n", zfs_prop_to_name(ZFS_PROP_COMPRESSION),
871 		    zfs_get_name(zhp));
872 #endif
873 	}
874 
875 	prop = create_RecordSizeProperty(env, zhp);
876 	/* Does this property apply to this object? */
877 	if (prop != NULL) {
878 
879 		(*env)->CallBooleanMethod(env,
880 		    ((zjni_Object_t *)proplist)->object,
881 		    ((zjni_Collection_t *)proplist)->method_add, prop);
882 	} else {
883 		if ((*env)->ExceptionOccurred(env) != NULL) {
884 			return (NULL);
885 		}
886 #ifdef	DEBUG
887 		(void) fprintf(stderr, "Property %s is not appropriate "
888 		    "for %s\n", zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
889 		    zfs_get_name(zhp));
890 #endif
891 	}
892 
893 	prop = create_DateProperty(env, zhp, ZFS_PROP_CREATION);
894 	/* Does this property apply to this object? */
895 	if (prop != NULL) {
896 
897 		(*env)->CallBooleanMethod(env,
898 		    ((zjni_Object_t *)proplist)->object,
899 		    ((zjni_Collection_t *)proplist)->method_add, prop);
900 	} else {
901 		if ((*env)->ExceptionOccurred(env) != NULL) {
902 			return (NULL);
903 		}
904 #ifdef	DEBUG
905 		(void) fprintf(stderr, "Property %s is not appropriate "
906 		    "for %s\n", zfs_prop_to_name(ZFS_PROP_CREATION),
907 		    zfs_get_name(zhp));
908 #endif
909 	}
910 
911 	return (zjni_Collection_to_array(
912 	    env, (zjni_Collection_t *)proplist,
913 	    ZFSJNI_PACKAGE_DATA "Property"));
914 }
915 
916 static jobject
917 create_default_BooleanProperty(JNIEnv *env, zfs_prop_t prop)
918 {
919 	jobject propertyObject = NULL;
920 
921 	if (!zfs_prop_readonly(prop)) {
922 
923 		jclass class_BooleanProperty = (*env)->FindClass(env,
924 		    ZFSJNI_PACKAGE_DATA "BooleanProperty");
925 
926 		jmethodID constructor_BooleanProperty = (*env)->GetMethodID(
927 		    env, class_BooleanProperty, "<init>",
928 		    "(Ljava/lang/String;Ljava/lang/Boolean;ZL"
929 		    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
930 
931 		jstring propName =
932 		    (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
933 		jobject propValue =
934 		    zjni_int_to_boolean(env, zfs_prop_default_numeric(prop));
935 		jboolean readOnly = zfs_prop_readonly(prop) ?
936 		    JNI_TRUE : JNI_FALSE;
937 		jobject lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
938 
939 		propertyObject = (*env)->NewObject(
940 		    env, class_BooleanProperty, constructor_BooleanProperty,
941 		    propName, propValue, readOnly, lineage);
942 	}
943 
944 	return (propertyObject);
945 }
946 
947 static jobject
948 create_default_LongProperty(JNIEnv *env, zfs_prop_t prop)
949 {
950 	jobject propertyObject = NULL;
951 
952 	if (!zfs_prop_readonly(prop)) {
953 
954 		jclass class_LongProperty = (*env)->FindClass(env,
955 		    ZFSJNI_PACKAGE_DATA "LongProperty");
956 
957 		jmethodID constructor_LongProperty = (*env)->GetMethodID(
958 		    env, class_LongProperty, "<init>",
959 		    "(Ljava/lang/String;Ljava/lang/Long;ZL"
960 		    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
961 
962 		jstring propName =
963 		    (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
964 		jobject propValue =
965 		    zjni_long_to_Long(env, zfs_prop_default_numeric(prop));
966 		jboolean readOnly = zfs_prop_readonly(prop)
967 		    ? JNI_TRUE : JNI_FALSE;
968 		jobject lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
969 
970 		propertyObject = (*env)->NewObject(
971 		    env, class_LongProperty, constructor_LongProperty,
972 		    propName, propValue, readOnly, lineage);
973 	}
974 
975 	return (propertyObject);
976 }
977 
978 static jobject
979 create_default_StringProperty(JNIEnv *env, zfs_prop_t prop)
980 {
981 	jobject propertyObject = NULL;
982 
983 	if (zfs_prop_is_string(prop) && !zfs_prop_readonly(prop)) {
984 
985 		char propbuf[ZFS_MAXPROPLEN];
986 		jclass class_StringProperty;
987 		jmethodID constructor_StringProperty;
988 		jstring propName;
989 		jobject propValue;
990 		jboolean readOnly;
991 		jobject lineage;
992 
993 		zfs_prop_default_string(prop, propbuf, sizeof (propbuf));
994 
995 		class_StringProperty =
996 		    (*env)->FindClass(env,
997 			ZFSJNI_PACKAGE_DATA "StringProperty");
998 
999 		constructor_StringProperty = (*env)->GetMethodID(
1000 		    env, class_StringProperty, "<init>",
1001 		    "(Ljava/lang/String;Ljava/lang/String;ZL"
1002 		    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
1003 
1004 		propName = (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
1005 		propValue = (*env)->NewStringUTF(env, propbuf);
1006 		readOnly = zfs_prop_readonly(prop) ? JNI_TRUE : JNI_FALSE;
1007 		lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
1008 
1009 		propertyObject = (*env)->NewObject(
1010 		    env, class_StringProperty, constructor_StringProperty,
1011 		    propName, propValue, readOnly, lineage);
1012 	}
1013 
1014 	return (propertyObject);
1015 }
1016 
1017 static jobject
1018 create_default_MountPointProperty(JNIEnv *env)
1019 {
1020 	jobject propertyObject = NULL;
1021 
1022 	char propbuf[ZFS_MAXPROPLEN];
1023 	jclass class_MountPointProperty;
1024 	jmethodID constructor_MountPointProperty;
1025 	jobject propValue;
1026 	jobject lineage;
1027 
1028 	zfs_prop_default_string(ZFS_PROP_MOUNTPOINT, propbuf, sizeof (propbuf));
1029 
1030 	class_MountPointProperty = (*env)->FindClass(
1031 	    env, ZFSJNI_PACKAGE_DATA "MountPointProperty");
1032 
1033 	propValue = (*env)->NewStringUTF(env, propbuf);
1034 	lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
1035 
1036 	constructor_MountPointProperty = (*env)->GetMethodID(
1037 	    env, class_MountPointProperty, "<init>",
1038 	    "(Ljava/lang/String;L"
1039 	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
1040 
1041 	propertyObject = (*env)->NewObject(
1042 	    env, class_MountPointProperty, constructor_MountPointProperty,
1043 	    propValue, lineage);
1044 
1045 	return (propertyObject);
1046 }
1047 
1048 static jobject
1049 create_default_ShareNFSProperty(JNIEnv *env)
1050 {
1051 	jobject propertyObject = NULL;
1052 
1053 	char propbuf[ZFS_MAXPROPLEN];
1054 	jclass class_ShareNFSProperty;
1055 	jmethodID constructor_ShareNFSProperty;
1056 	jobject propValue;
1057 	jobject lineage;
1058 
1059 	zfs_prop_default_string(ZFS_PROP_SHARENFS, propbuf, sizeof (propbuf));
1060 
1061 	class_ShareNFSProperty = (*env)->FindClass(
1062 	    env, ZFSJNI_PACKAGE_DATA "ShareNFSProperty");
1063 
1064 	propValue = (*env)->NewStringUTF(env, propbuf);
1065 	lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
1066 
1067 	constructor_ShareNFSProperty = (*env)->GetMethodID(
1068 	    env, class_ShareNFSProperty, "<init>",
1069 	    "(Ljava/lang/String;L"
1070 	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
1071 
1072 	propertyObject = (*env)->NewObject(
1073 	    env, class_ShareNFSProperty, constructor_ShareNFSProperty,
1074 	    propValue, lineage);
1075 
1076 	return (propertyObject);
1077 }
1078 
1079 static jobject
1080 create_default_ChecksumProperty(JNIEnv *env)
1081 {
1082 	jobject propertyObject = NULL;
1083 
1084 	char propbuf[ZFS_MAXPROPLEN];
1085 	jclass class_ChecksumProperty;
1086 	jmethodID constructor_ChecksumProperty;
1087 	jobject propValue;
1088 	jobject lineage;
1089 
1090 	zfs_prop_default_string(ZFS_PROP_CHECKSUM, propbuf, sizeof (propbuf));
1091 	propValue = str_to_checksum(env, propbuf);
1092 
1093 	class_ChecksumProperty = (*env)->FindClass(
1094 	    env, ZFSJNI_PACKAGE_DATA "ChecksumProperty");
1095 
1096 	lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
1097 
1098 	constructor_ChecksumProperty = (*env)->GetMethodID(
1099 	    env, class_ChecksumProperty, "<init>",
1100 	    "(L" ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum;L"
1101 	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
1102 
1103 	propertyObject = (*env)->NewObject(env,
1104 	    class_ChecksumProperty, constructor_ChecksumProperty,
1105 	    propValue, lineage);
1106 
1107 	return (propertyObject);
1108 }
1109 
1110 static jobject
1111 create_default_CompressionProperty(JNIEnv *env)
1112 {
1113 	jobject propertyObject = NULL;
1114 
1115 	char propbuf[ZFS_MAXPROPLEN];
1116 	jclass class_CompressionProperty;
1117 	jmethodID constructor_CompressionProperty;
1118 	jobject propValue;
1119 	jobject lineage;
1120 
1121 	zfs_prop_default_string(
1122 	    ZFS_PROP_COMPRESSION, propbuf, sizeof (propbuf));
1123 	propValue = str_to_compression(env, propbuf);
1124 
1125 	class_CompressionProperty = (*env)->FindClass(
1126 	    env, ZFSJNI_PACKAGE_DATA "CompressionProperty");
1127 
1128 	lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
1129 
1130 	constructor_CompressionProperty = (*env)->GetMethodID(
1131 	    env, class_CompressionProperty, "<init>",
1132 	    "(L" ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression;L"
1133 	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
1134 
1135 	propertyObject = (*env)->NewObject(env,
1136 	    class_CompressionProperty, constructor_CompressionProperty,
1137 	    propValue, lineage);
1138 
1139 	return (propertyObject);
1140 }
1141 
1142 static jobject
1143 create_default_RecordSizeProperty(JNIEnv *env)
1144 {
1145 	jclass class_RecordSizeProperty = (*env)->FindClass(env,
1146 	    ZFSJNI_PACKAGE_DATA "RecordSizeProperty");
1147 
1148 	jmethodID constructor_RecordSizeProperty = (*env)->GetMethodID(
1149 	    env, class_RecordSizeProperty, "<init>",
1150 	    "(Ljava/lang/Long;L"
1151 	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
1152 
1153 	jobject propValue = zjni_long_to_Long(
1154 	    env, zfs_prop_default_numeric(ZFS_PROP_RECORDSIZE));
1155 
1156 	jobject lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
1157 
1158 	jobject propertyObject = (*env)->NewObject(
1159 	    env, class_RecordSizeProperty, constructor_RecordSizeProperty,
1160 	    propValue, lineage);
1161 
1162 	return (propertyObject);
1163 }
1164