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