/*
* Geopaparazzi - Digital field mapping on Android based devices
* Copyright (C) 2016 HydroloGIS (www.hydrologis.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.geopaparazzi.library.profiles;
import android.content.ContentResolver;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.NonNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import eu.geopaparazzi.library.core.maps.BaseMap;
import eu.geopaparazzi.library.util.FileUtilities;
import eu.geopaparazzi.library.util.types.ESpatialDataSources;
/**
* Profile handling related stuff.
*
* @author Andrea Antonello
*/
public enum ProfilesHandler {
INSTANCE;
public static final String KEY_PROFILES_PREFERENCES = "KEY_PROFILES_PREFERENCES";
public static final String NAME = "name";
public static final String DESCRIPTION = "description";
public static final String CREATIONDATE = "creationdate";
public static final String COLOR = "color";
public static final String ACTIVE = "active";
public static final String TAGS_PATH = "tagsPath";
public static final String PROJECT_PATH = "projectPath";
public static final String SDCARD_PATH = "sdcardPath";
public static final String BASEMAPS = "basemaps";
public static final String PATH = "path";
public static final String SPATIALITE = "spatialitedbs";
public static final String PROFILES = "profiles";
public static final String[] CONTENT_PROVIDER_FIELDS = new String[]{"name", "isactive", "json"};
public static final String AUTHORITY = "eu.geopaparazzi.provider.profiles";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + AUTHORITY);
public static final String PROFILE = "profile";
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PROFILE).build();
/**
* The active profile.
*/
private Profile activeProfile;
/**
* Get the list of stored profiles from the preferences.
*
* @param preferences the preferences object.
* @return the list of Profile objects.
* @throws JSONException
*/
public List<Profile> getProfilesFromPreferences(SharedPreferences preferences) throws JSONException {
String profilesJson = preferences.getString(KEY_PROFILES_PREFERENCES, "");
return getProfilesFromJson(profilesJson);
}
/**
* Save the list of profiles to preferences.
*
* @param preferences the preferences object.
* @throws JSONException
*/
public void saveProfilesToPreferences(SharedPreferences preferences, List<Profile> profilesList) throws JSONException {
String jsonProfilesString = getJsonFromProfilesList(profilesList, false);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(KEY_PROFILES_PREFERENCES, jsonProfilesString);
editor.apply();
}
/**
* Get the list of profiles from a json text.
*
* @param profilesJson the json text.
* @return the list of Profile objects.
* @throws JSONException
*/
@NonNull
public List<Profile> getProfilesFromJson(String profilesJson) throws JSONException {
List<Profile> profilesList = new ArrayList<>();
if (profilesJson.trim().length() == 0)
return profilesList;
JSONObject root = new JSONObject(profilesJson);
JSONArray profilesArray = root.getJSONArray(PROFILES);
for (int i = 0; i < profilesArray.length(); i++) {
JSONObject profileObject = profilesArray.getJSONObject(i);
Profile profile = getProfileFromJson(profileObject);
profilesList.add(profile);
}
return profilesList;
}
/**
* Extract a profile from a json object.
*
* @param profileObject the json object.
* @return the profile.
* @throws JSONException
*/
public Profile getProfileFromJson(JSONObject profileObject) throws JSONException {
Profile profile = new Profile();
if (profileObject.has(NAME)) {
profile.name = profileObject.getString(NAME);
}
if (profileObject.has(DESCRIPTION)) {
profile.description = profileObject.getString(DESCRIPTION);
}
if (profileObject.has(CREATIONDATE)) {
profile.creationdate = profileObject.getString(CREATIONDATE);
}
if (profileObject.has(COLOR)) {
profile.color = profileObject.getString(COLOR);
}
if (profileObject.has(ACTIVE)) {
profile.active = profileObject.getBoolean(ACTIVE);
}
if (profileObject.has(TAGS_PATH)) {
profile.tagsPath = profileObject.getString(TAGS_PATH);
}
if (profileObject.has(PROJECT_PATH)) {
profile.projectPath = profileObject.getString(PROJECT_PATH);
}
if (profileObject.has(SDCARD_PATH)) {
profile.sdcardPath = profileObject.getString(SDCARD_PATH);
}
if (profileObject.has(BASEMAPS)) {
JSONArray basemapsArray = profileObject.getJSONArray(BASEMAPS);
for (int j = 0; j < basemapsArray.length(); j++) {
JSONObject baseMapObject = basemapsArray.getJSONObject(j);
if (baseMapObject.has(PATH)) {
String path = baseMapObject.getString(PATH);
profile.basemapsList.add(path);
}
}
}
if (profileObject.has(SPATIALITE)) {
JSONArray spatialiteDbsArray = profileObject.getJSONArray(SPATIALITE);
for (int j = 0; j < spatialiteDbsArray.length(); j++) {
JSONObject spatialiteDbsObject = spatialiteDbsArray.getJSONObject(j);
if (spatialiteDbsObject.has(PATH)) {
String path = spatialiteDbsObject.getString(PATH);
profile.spatialiteList.add(path);
}
}
}
return profile;
}
/**
* Get the json text from a list of profiles.
*
* @param profilesList the list of profiles.
* @param indent optional json indenting flag.
* @return the json string.
* @throws JSONException
*/
public String getJsonFromProfilesList(List<Profile> profilesList, boolean indent) throws JSONException {
JSONObject root = new JSONObject();
JSONArray profilesArray = new JSONArray();
root.put(PROFILES, profilesArray);
for (Profile profile : profilesList) {
JSONObject profileObject = getJsonFromProfile(profile);
profilesArray.put(profileObject);
}
if (indent)
return root.toString(2);
else
return root.toString();
}
/**
* Converts a profile object to a json object.
*
* @param profile the profile.
* @return the json obj.
* @throws JSONException
*/
public JSONObject getJsonFromProfile(Profile profile) throws JSONException {
JSONObject profileObject = new JSONObject();
profileObject.put(NAME, profile.name);
profileObject.put(DESCRIPTION, profile.description);
profileObject.put(CREATIONDATE, profile.creationdate);
profileObject.put(COLOR, profile.color);
profileObject.put(ACTIVE, profile.active);
profileObject.put(TAGS_PATH, profile.tagsPath);
profileObject.put(PROJECT_PATH, profile.projectPath);
profileObject.put(SDCARD_PATH, profile.sdcardPath);
if (profile.basemapsList.size() > 0) {
JSONArray basemapsArray = new JSONArray();
for (int j = 0; j < profile.basemapsList.size(); j++) {
JSONObject baseMapObject = new JSONObject();
baseMapObject.put(PATH, profile.basemapsList.get(j));
basemapsArray.put(j, baseMapObject);
}
profileObject.put(BASEMAPS, basemapsArray);
}
if (profile.spatialiteList.size() > 0) {
JSONArray spatialiteDbsArray = new JSONArray();
for (int j = 0; j < profile.spatialiteList.size(); j++) {
JSONObject spatialiteDbObject = new JSONObject();
spatialiteDbObject.put(PATH, profile.spatialiteList.get(j));
spatialiteDbsArray.put(spatialiteDbObject);
}
profileObject.put(SPATIALITE, spatialiteDbsArray);
}
return profileObject;
}
/**
* Getter for the active profile.
*
* @return the active profile or null if there is none.
*/
public Profile getActiveProfile() {
return activeProfile;
}
/**
* Get the active profile from a contentresolver.
*
* @param contentResolver the resolver to use.
* @throws JSONException
*/
public void checkActiveProfile(ContentResolver contentResolver) throws JSONException {
activeProfile = null;
String[] projection = CONTENT_PROVIDER_FIELDS;
Cursor cursor = contentResolver.query(CONTENT_URI,
projection,
null,
null,
null);
if (cursor != null && cursor.moveToFirst()) {
do {
String name = cursor.getString(0);
boolean active = cursor.getInt(1) != 0;
if (name != null && active) {
String json = cursor.getString(2);
JSONObject profileObject = new JSONObject(json);
activeProfile = ProfilesHandler.INSTANCE.getProfileFromJson(profileObject);
}
} while (cursor.moveToNext());
cursor.close();
}
}
public List<BaseMap> getBaseMaps() {
List<BaseMap> baseMaps = new ArrayList<>();
if (activeProfile != null) {
for (String baseMapPath : activeProfile.basemapsList) {
BaseMap map = new BaseMap();
File databaseFile = new File(baseMapPath);
if (databaseFile.exists()) {
map.parentFolder = databaseFile.getParentFile().getAbsolutePath();
map.databasePath = databaseFile.getAbsolutePath();
map.title = FileUtilities.getNameWithoutExtention(databaseFile);
map.mapType = ESpatialDataSources.getTypeName4FileName(databaseFile.getName());
baseMaps.add(map);
}
}
}
return baseMaps;
}
}