Services to save/load data using android.content.SharedPreferences for the android platform

Introduced classes

class SharedPreferences

android :: SharedPreferences

Provides services to save and load data for the android platform

Redefined classes

redef class App

android :: shared_preferences_api10 $ App

App subclasses are cross-platform applications

All class definitions

redef class App

android :: shared_preferences_api10 $ App

App subclasses are cross-platform applications
class SharedPreferences

android $ SharedPreferences

Provides services to save and load data for the android platform
package_diagram android::shared_preferences_api10 shared_preferences_api10 android::dalvik dalvik android::shared_preferences_api10->android::dalvik json json android::shared_preferences_api10->json android::activities activities android::dalvik->android::activities parser_base parser_base json->parser_base serialization serialization json->serialization ...android::activities ... ...android::activities->android::activities ...parser_base ... ...parser_base->parser_base ...serialization ... ...serialization->serialization android::shared_preferences shared_preferences android::shared_preferences->android::shared_preferences_api10 android::data_store data_store android::data_store->android::shared_preferences android::shared_preferences_api11 shared_preferences_api11 android::shared_preferences_api11->android::shared_preferences android::data_store... ... android::data_store...->android::data_store android::shared_preferences_api11... ... android::shared_preferences_api11...->android::shared_preferences_api11

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module activities

android :: activities

Android Activities wrapper
module app

app :: app

app.nit is a framework to create cross-platform applications
module app_base

app :: app_base

Base of the app.nit framework, defines App
module array

core :: array

This module introduces the standard array structure.
module assets

app :: assets

Portable services to load resources from the assets folder
module aware

android :: aware

Android compatibility module
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module caching

serialization :: caching

Services for caching serialization engines
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module collections

java :: collections

Basic Java collections
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

json :: error

Intro JsonParseError which is exposed by all JSON reading APIs
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module ffi_support

java :: ffi_support

Core supporting services for the FFI with Java
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module java

java :: java

Supporting services for the FFI with Java and to access Java libraries
module jvm

jvm :: jvm

Java Virtual Machine invocation API and others services from the JNI C API
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module parser_base

parser_base :: parser_base

Simple base for hand-made parsers of all kinds
module platform

android :: platform

Triggers compilation for the android platform
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module safe

serialization :: safe

Services for safer deserialization engines
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module serialization_read

json :: serialization_read

Services to read JSON: deserialize_json and JsonDeserializer
module serialization_write

json :: serialization_write

Services to write Nit objects to JSON strings: serialize_to_json and JsonSerializer
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module static

json :: static

Static interface to read Nit objects from JSON strings
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module dalvik

android :: dalvik

Java related services specific to Android and its Dalvik VM
module json

json :: json

Read and write JSON formatted text using the standard serialization services

Children

module shared_preferences

android :: shared_preferences

Services allowing to save and load datas to internal android device

Descendants

module a_star-m

a_star-m

module data_store

android :: data_store

Implements app::data_store using shared_preferences
module http_request

android :: http_request

Android implementation of app:http_request
module shared_preferences_api11

android :: shared_preferences_api11

Refines shared_preferences module to add API 11 services
module ui

android :: ui

Views and services to use the Android native user interface
module ui_test

android :: ui_test

Test for app.nit's UI services
# Services to save/load data using `android.content.SharedPreferences` for the android platform
module shared_preferences_api10

import dalvik
import serialization
private import json

in "Java" `{
	import android.content.SharedPreferences;
	import android.content.Context;
	import android.app.Activity;
	import java.util.Map;
	import java.util.Iterator;
	import java.lang.ClassCastException;
	import java.lang.NullPointerException;
`}

extern class NativeSharedPreferences in "Java" `{ android.content.SharedPreferences `}
	super JavaObject

	fun contains(key: JavaString): Bool in "Java" `{ return self.contains(key); `}
	fun get_all: HashMap[JavaString, JavaObject] import HashMap[JavaString, JavaObject],
		HashMap[JavaString, JavaObject].[]= in "Java" `{
		Map<String, ?> java_map = null;
		nit.app.NitObject nit_hashmap = new_HashMap_of_JavaString_JavaObject();
		try {
			java_map = self.getAll();
		} catch (NullPointerException e) {
			return nit_hashmap;
		}

		for (Map.Entry<String, ?> entry: java_map.entrySet())
			HashMap_of_JavaString_JavaObject__index_assign(nit_hashmap,
				entry.getKey(), entry.getValue());

		return nit_hashmap;
	`}
	fun get_boolean(key: JavaString, def_value: Bool): Bool in "Java" `{
		boolean return_value;
		try {
			return_value = self.getBoolean(key, def_value);
		} catch (ClassCastException e) {
			return def_value;
		}

		return return_value;
	`}
	fun get_float(key: JavaString, def_value: Float): Float in "Java" `{
		float return_value;
		try {
			return_value = self.getFloat(key, (float) def_value);
		} catch (ClassCastException e) {
			return def_value;
		}

		return return_value;
	`}
	fun get_int(key: JavaString, def_value: Int): Int in "Java" `{
		int return_value;
		try {
			return_value = self.getInt(key, (int)def_value);
		} catch (ClassCastException e) {
			return def_value;
		}

		return return_value;
	`}
	fun get_long(key: JavaString, def_value: Int): Int in "Java" `{
		long return_value;
		try {
			return_value = self.getLong(key, def_value);
		} catch (ClassCastException e) {
			return def_value;
		}

		return (int) return_value;
	`}
	fun get_string(key: JavaString, def_value: JavaString): JavaString in "Java" `{
		String return_value = null;
		try {
			return_value = self.getString(key, def_value);
		} catch (ClassCastException e) {
			return def_value;
		}

		return return_value;
	`}

	# HACK for bug #845
	redef fun new_global_ref import sys, Sys.jni_env `{
		Sys sys = NativeSharedPreferences_sys(self);
		JNIEnv *env = Sys_jni_env(sys);
		return (*env)->NewGlobalRef(env, self);
	`}
end

extern class NativeSharedPreferencesEditor in "Java" `{ android.content.SharedPreferences$Editor `}
	super JavaObject

	fun clear: NativeSharedPreferencesEditor in "Java" `{ return self.clear(); `}
	fun commit: Bool in "Java" `{ return self.commit(); `}
	fun put_boolean(key: JavaString, value: Bool): NativeSharedPreferencesEditor in "Java" `{
		return self.putBoolean (key, value);
	`}
	fun put_float(key: JavaString, value: Float): NativeSharedPreferencesEditor in "Java" `{
		return self.putFloat(key, (float) value);
	`}
	fun put_int(key: JavaString, value: Int): NativeSharedPreferencesEditor in "Java" `{
		return self.putInt(key, (int)value);
	`}
	fun put_long(key: JavaString, value: Int): NativeSharedPreferencesEditor in "Java" `{
		return self.putLong(key, value);
	`}
	fun put_string(key: JavaString, value: JavaString): NativeSharedPreferencesEditor in "Java" `{
		return self.putString(key, value);
	`}
	fun remove(key: JavaString): NativeSharedPreferencesEditor in "Java" `{
		return self.remove(key);
	`}

	# HACK for bug #845
	redef fun new_global_ref import sys, Sys.jni_env `{
		Sys sys = NativeSharedPreferencesEditor_sys(self);
		JNIEnv *env = Sys_jni_env(sys);
		return (*env)->NewGlobalRef(env, self);
	`}
end

# Provides services to save and load data for the android platform
class SharedPreferences
	protected var shared_preferences: NativeSharedPreferences
	protected var editor: NativeSharedPreferencesEditor

	# Automatically commits every saving/removing instructions (`true` by default)
	var auto_commit = true

	protected init(app: App, file_name: String, mode: Int)
	do
		sys.jni_env.push_local_frame(1)
		setup(file_name.to_java_string, mode, app.native_context)
		sys.jni_env.pop_local_frame
	end

	# Restricts file access to the current application
	init privately(app: App, file_name: String)
	do
		self.init(app, file_name, private_mode)
	end

	# File access mode
	private fun private_mode: Int in "Java" `{ return Context.MODE_PRIVATE; `}

	private fun set_vars(shared_pref: NativeSharedPreferences, editor: NativeSharedPreferencesEditor)
	do
		self.shared_preferences = shared_pref.new_global_ref
		self.editor = editor.new_global_ref
	end

	private fun setup(file_name: JavaString, mode: Int, context: NativeContext) import set_vars in "Java" `{
		SharedPreferences sp;

		// Uses default SharedPreferences if file_name is an empty String
		if (file_name.equals("")) {
			Activity activity = (Activity)context;
			sp = activity.getPreferences((int)mode);
		} else {
			sp = context.getSharedPreferences(file_name, (int)mode);
		}

		SharedPreferences.Editor editor = sp.edit();

		SharedPreferences_set_vars(self, sp, editor);
	`}

	private fun commit_if_auto do if auto_commit then self.commit

	# Returns true if there's an entry corresponding the given key
	fun has(key: String): Bool
	do
		sys.jni_env.push_local_frame(2)
		var return_value = shared_preferences.contains(key.to_java_string)
		sys.jni_env.pop_local_frame
		return return_value
	end

	# Returns a `HashMap` containing all entries or `null` if there's no entries
	#
	# User has to manage local stack deallocation himself
	#
	# ~~~nitish
	# var foo = new HashMap[JavaString, JavaObject]
	# # ...
	# for key, value in foo do
	#	  key.delete_local_ref
	#	  value.delete_local_ref
	# end
	# ~~~
	# *You should use Nit getters instead and get each value one by one*
	fun all: nullable HashMap[JavaString, JavaObject]
	do
		var hashmap = shared_preferences.get_all
		if hashmap.is_empty then return null
		return hashmap
	end

	# Returns the `Bool` value corresponding the given key or `def_value` if none
	# or if the value isn't of correct type
	fun bool(key: String, def_value: Bool): Bool
	do
		sys.jni_env.push_local_frame(2)
		var return_value = shared_preferences.get_boolean(key.to_java_string, def_value)
		sys.jni_env.pop_local_frame
		return return_value
	end

	# Returns the `Float` value corresponding the given key or `def_value` if none
	# or if the value isn't of correct type
	fun float(key: String, def_value: Float): Float
	do
		sys.jni_env.push_local_frame(2)
		var return_value = shared_preferences.get_float(key.to_java_string, def_value)
		sys.jni_env.pop_local_frame
		return return_value
	end

	# Returns the `Int` value corresponding the given key or `def_value` if none
	# or if the value isn't of correct type
	# Be aware of possible `def_value` integer overflow as the Nit `Int` corresponds
	# to Java `long`
	fun int(key: String, def_value: Int): Int
	do
		sys.jni_env.push_local_frame(2)
		var return_value = shared_preferences.get_int(key.to_java_string, def_value)
		sys.jni_env.pop_local_frame
		return return_value
	end

	# Returns the `Int` value corresponding the given key or `def_value` if none
	# or if the value isn't of correct type
	# Calls `getLong(key, value)` java method
	# Nit `Int` is equivalent to Java `long` so that no integer overflow will occur
	fun long(key: String, def_value: Int): Int
	do
		sys.jni_env.push_local_frame(2)
		var return_value = shared_preferences.get_long(key.to_java_string, def_value)
		sys.jni_env.pop_local_frame
		return return_value
	end

	# Returns the `String` value corresponding the given key or `def_value` if none
	# or if the value isn't of correct type
	fun string(key: String, def_value: String): String
	do
		sys.jni_env.push_local_frame(3)
		var java_return_value = shared_preferences.get_string(key.to_java_string,
			def_value.to_java_string)
		var nit_return_value = java_return_value.to_s
		sys.jni_env.pop_local_frame
		return nit_return_value
	end

	# Clears all the dictionnary entries in the specified file or the default file
	# if none specified at instanciation
	# Returns `self` allowing fluent programming
	fun clear: SharedPreferences
	do
		editor.clear
		commit_if_auto
		return self
	end

	# If auto_commit is `false`, has to be called to save the data to persistant memory
	fun commit: Bool
	do
		sys.jni_env.push_local_frame(1)
		var return_value = editor.commit
		sys.jni_env.pop_local_frame
		return return_value
	end

	# Set a key-value pair using a `Bool` value
	# Returns `self` allowing fluent programming
	fun add_bool(key: String, value: Bool): SharedPreferences
	do
		sys.jni_env.push_local_frame(1)
		editor.put_boolean(key.to_java_string, value)
		sys.jni_env.pop_local_frame
		commit_if_auto
		return self
	end

	# Set a key-value pair using a `Float` value
	# Returns `self` allowing fluent programming
	#
	# Be aware of possible loss of precision as Nit `Float` corresponds to Java `double`
	# and the methods stores a Java `float`
	fun add_float(key: String, value: Float): SharedPreferences
	do
		sys.jni_env.push_local_frame(1)
		editor.put_float(key.to_java_string, value)
		sys.jni_env.pop_local_frame
		commit_if_auto
		return self
	end

	# Set a key-value pair using a `Int` type value
	# Returns `self` allowing fluent programming
	#
	# Be aware of possible integer overflow as the Nit `Int` corresponds to Java `long`
	# and the methods stores a Java `int`
	# *You might want to use add_long instead*
	fun add_int(key: String, value: Int): SharedPreferences
	do
		sys.jni_env.push_local_frame(1)
		editor.put_int(key.to_java_string, value)
		sys.jni_env.pop_local_frame
		commit_if_auto
		return self
	end

	# Set a key-value pair using a `Int` type value
	# Returns `self` allowing fluent programming
	fun add_long(key: String, value: Int): SharedPreferences
	do
		sys.jni_env.push_local_frame(1)
		editor.put_long(key.to_java_string, value)
		sys.jni_env.pop_local_frame
		commit_if_auto
		return self
	end

	# Set a key-value pair using a `String` type value
	# Returns `self` allowing fluent programming
	fun add_string(key: String, value: String): SharedPreferences
	do
		sys.jni_env.push_local_frame(2)
		editor.put_string(key.to_java_string, value.to_java_string)
		sys.jni_env.pop_local_frame
		commit_if_auto
		return self
	end

	# Removes the corresponding entry in the file
	# Returns `self` allowing fluent programming
	fun remove(key: String): SharedPreferences
	do
		sys.jni_env.push_local_frame(1)
		editor.remove(key.to_java_string)
		sys.jni_env.pop_local_frame
		commit_if_auto
		return self
	end

	# Deallocate global references allocated by the SharedPreferences instance
	fun destroy
	do
		self.shared_preferences.delete_global_ref
		self.editor.delete_global_ref
	end

	# Store `value` as a serialized Json string
	fun []=(key: String, value: nullable Serializable)
	do
		var serialized_string = new StringWriter
		var serializer = new JsonSerializer(serialized_string)
		serializer.serialize(value)

		add_string(key, serialized_string.to_s)
		commit_if_auto
	end

	# Retrieve an `Object` stored via `[]=` function
	#
	# Returns `null` if there's no serialized object corresponding to the given key
	# Make sure that the serialized object is `serialize` or that it redefines
	# the appropriate methods. Refer to `Serializable` documentation for further details
	fun [](key: String): nullable Object
	do
		var serialized_string = self.string(key, "")

		if serialized_string == "" then return null

		var deserializer = new JsonDeserializer(serialized_string)
		var deserialized = deserializer.deserialize

		var errors = deserializer.errors
		if errors.not_empty then
			# An update may have broken the versioning compatibility
			print_error "{class_name} error at deserialization: {errors.join(", ")}"
			return null # Let's be safe
		end

		return deserialized
	end
end

redef class App
	var shared_preferences: SharedPreferences is lazy do
		return new SharedPreferences.privately(self, "app.nit")
	end
end
lib/android/shared_preferences/shared_preferences_api10.nit:17,1--417,3