Save plugin items to json

This commit is contained in:
Vitaliy 2020-03-24 16:45:34 +02:00
parent 235028d317
commit d01b5106ef
4 changed files with 148 additions and 82 deletions

View file

@ -1,8 +1,10 @@
package net.osmand.plus; package net.osmand.plus;
import android.app.Activity;
import android.content.res.Configuration; import android.content.res.Configuration;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -31,23 +33,7 @@ public class CustomOsmandPlugin extends OsmandPlugin {
public CustomOsmandPlugin(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException { public CustomOsmandPlugin(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(app); super(app);
pluginId = json.getString("pluginId"); pluginId = json.getString("pluginId");
readAdditionalDataFromJson(json);
JSONObject nameJson = json.getJSONObject("name");
if (nameJson != null) {
for (Iterator<String> it = nameJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = nameJson.getString(localeKey);
names.put(localeKey, name);
}
}
JSONObject descriptionJson = json.getJSONObject("description");
if (descriptionJson != null) {
for (Iterator<String> it = descriptionJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = descriptionJson.getString(localeKey);
descriptions.put(localeKey, name);
}
}
} }
// Prepare ".opr" desert-package manually + add all resources inside (extend json to describe package). // Prepare ".opr" desert-package manually + add all resources inside (extend json to describe package).
@ -64,6 +50,16 @@ public class CustomOsmandPlugin extends OsmandPlugin {
// so we could remove all code for Nautical / Ski Maps from OsmAnd // so we could remove all code for Nautical / Ski Maps from OsmAnd
// and put to separate "skimaps.opr", "nautical.opr" in future // and put to separate "skimaps.opr", "nautical.opr" in future
@Override
public boolean init(@NonNull OsmandApplication app, @Nullable Activity activity) {
return super.init(app, activity);
}
@Override
public void disable(OsmandApplication app) {
super.disable(app);
}
@Override @Override
public String getId() { public String getId() {
return pluginId; return pluginId;
@ -104,12 +100,26 @@ public class CustomOsmandPlugin extends OsmandPlugin {
return R.drawable.ic_action_skiing; return R.drawable.ic_action_skiing;
} }
public String toJson() throws JSONException { public void readAdditionalDataFromJson(JSONObject json) throws JSONException {
JSONObject json = new JSONObject(); JSONObject nameJson = json.has("name") ? json.getJSONObject("name") : null;
if (nameJson != null) {
json.put("type", SettingsHelper.SettingsItemType.PLUGIN.name()); for (Iterator<String> it = nameJson.keys(); it.hasNext(); ) {
json.put("pluginId", getId()); String localeKey = it.next();
String name = nameJson.getString(localeKey);
names.put(localeKey, name);
}
}
JSONObject descriptionJson = json.has("description") ? json.getJSONObject("description") : null;
if (descriptionJson != null) {
for (Iterator<String> it = descriptionJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = descriptionJson.getString(localeKey);
descriptions.put(localeKey, name);
}
}
}
public void writeAdditionalDataToJson(JSONObject json) throws JSONException {
JSONObject nameJson = new JSONObject(); JSONObject nameJson = new JSONObject();
for (Map.Entry<String, String> entry : names.entrySet()) { for (Map.Entry<String, String> entry : names.entrySet()) {
nameJson.put(entry.getKey(), entry.getValue()); nameJson.put(entry.getKey(), entry.getValue());
@ -121,8 +131,6 @@ public class CustomOsmandPlugin extends OsmandPlugin {
descriptionJson.put(entry.getKey(), entry.getValue()); descriptionJson.put(entry.getKey(), entry.getValue());
} }
json.put("description", descriptionJson); json.put("description", descriptionJson);
return json.toString();
} }
@Override @Override

View file

@ -268,15 +268,12 @@ public abstract class OsmandPlugin {
activatePlugins(app, enabledPlugins); activatePlugins(app, enabledPlugins);
} }
public static void addCustomPlugin(@NonNull OsmandApplication app, @Nullable Activity activity, @NonNull CustomOsmandPlugin plugin) { public static void addCustomPlugin(@NonNull OsmandApplication app, @NonNull CustomOsmandPlugin plugin) {
OsmandPlugin oldPlugin = OsmandPlugin.getPlugin(plugin.getId()); OsmandPlugin oldPlugin = OsmandPlugin.getPlugin(plugin.getId());
if (oldPlugin != null) { if (oldPlugin != null) {
allPlugins.remove(oldPlugin); allPlugins.remove(oldPlugin);
} }
allPlugins.add(plugin); allPlugins.add(plugin);
if (activity != null) {
plugin.onInstall(app, activity);
}
initPlugin(app, plugin); initPlugin(app, plugin);
saveCustomPlugins(app); saveCustomPlugins(app);
} }
@ -307,7 +304,10 @@ public abstract class OsmandPlugin {
JSONArray itemsJson = new JSONArray(); JSONArray itemsJson = new JSONArray();
for (CustomOsmandPlugin plugin : customOsmandPlugins) { for (CustomOsmandPlugin plugin : customOsmandPlugins) {
try { try {
itemsJson.put(new JSONObject(plugin.toJson())); JSONObject json = new JSONObject();
json.put("pluginId", plugin.getId());
plugin.writeAdditionalDataToJson(json);
itemsJson.put(json);
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
} }

View file

@ -317,12 +317,17 @@ public class SettingsHelper {
public static class PluginSettingsItem extends SettingsItem { public static class PluginSettingsItem extends SettingsItem {
private CustomOsmandPlugin plugin; private CustomOsmandPlugin plugin;
private List<SettingsItem> pluginItems; private List<SettingsItem> pluginDependentItems;
PluginSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException { PluginSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(app, json); super(app, json);
} }
@Override
protected void init() {
pluginDependentItems = new ArrayList<>();
}
@NonNull @NonNull
@Override @Override
public SettingsItemType getType() { public SettingsItemType getType() {
@ -344,15 +349,30 @@ public class SettingsHelper {
@NonNull @NonNull
@Override @Override
public String getDefaultFileName() { public String getDefaultFileName() {
return getName() + ".zip"; return getName();
} }
public CustomOsmandPlugin getPlugin() { public CustomOsmandPlugin getPlugin() {
return plugin; return plugin;
} }
public List<SettingsItem> getPluginItems() { public List<SettingsItem> getPluginDependentItems() {
return pluginItems; return pluginDependentItems;
}
@Override
public void apply() {
for (SettingsHelper.SettingsItem item : pluginDependentItems) {
if (item instanceof SettingsHelper.FileSettingsItem) {
FileSettingsItem fileItem = (FileSettingsItem) item;
if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.RENDERING_STYLE) {
plugin.rendererNames.add(fileItem.getFileName());
} else if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.ROUTING_CONFIG) {
plugin.routerNames.add(fileItem.getFileName());
}
}
}
OsmandPlugin.addCustomPlugin(app, plugin);
} }
@Override @Override
@ -361,6 +381,12 @@ public class SettingsHelper {
plugin = new CustomOsmandPlugin(app, json); plugin = new CustomOsmandPlugin(app, json);
} }
@Override
void writeToJson(@NonNull JSONObject json) throws JSONException {
super.writeToJson(json);
plugin.writeAdditionalDataToJson(json);
}
@Nullable @Nullable
@Override @Override
SettingsItemReader getReader() { SettingsItemReader getReader() {
@ -1154,8 +1180,7 @@ public class SettingsHelper {
} }
String itemFileName = getFileName(); String itemFileName = getFileName();
if (itemFileName.endsWith(File.separator)) { if (itemFileName.endsWith(File.separator)) {
if (fileName.startsWith(itemFileName)) if (fileName.startsWith(itemFileName)) {
{
this.file = new File(getPluginPath(), fileName); this.file = new File(getPluginPath(), fileName);
return true; return true;
} else { } else {
@ -1866,7 +1891,10 @@ public class SettingsHelper {
for (SettingsItem item : items) { for (SettingsItem item : items) {
if (item instanceof PluginSettingsItem) { if (item instanceof PluginSettingsItem) {
PluginSettingsItem pluginSettingsItem = ((PluginSettingsItem) item); PluginSettingsItem pluginSettingsItem = ((PluginSettingsItem) item);
pluginSettingsItem.pluginItems = pluginItems.get(pluginSettingsItem.getName()); List<SettingsItem> pluginDependentItems = pluginItems.get(pluginSettingsItem.getName());
if (!Algorithms.isEmpty(pluginDependentItems)) {
pluginSettingsItem.getPluginDependentItems().addAll(pluginDependentItems);
}
} }
} }
} }
@ -1931,8 +1959,10 @@ public class SettingsHelper {
private Map<String, SettingsItem> items; private Map<String, SettingsItem> items;
private Map<String, String> additionalParams; private Map<String, String> additionalParams;
private boolean onlyJson;
SettingsExporter() { SettingsExporter(boolean onlyJson) {
this.onlyJson = onlyJson;
items = new LinkedHashMap<>(); items = new LinkedHashMap<>();
additionalParams = new LinkedHashMap<>(); additionalParams = new LinkedHashMap<>();
} }
@ -1949,16 +1979,26 @@ public class SettingsHelper {
} }
void exportSettings(File file) throws JSONException, IOException { void exportSettings(File file) throws JSONException, IOException {
JSONObject json = new JSONObject(); JSONObject json = createItemsJson();
json.put("version", VERSION); if (onlyJson) {
for (Map.Entry<String, String> param : additionalParams.entrySet()) { saveJsonItems(file, json);
json.put(param.getKey(), param.getValue()); } else {
saveZipItems(file, json);
} }
JSONArray itemsJson = new JSONArray(); }
for (SettingsItem item : items.values()) {
itemsJson.put(new JSONObject(item.toJson())); private void saveJsonItems(File file, JSONObject json) throws JSONException, IOException {
InputStream inputStream = new ByteArrayInputStream(json.toString(2).getBytes("UTF-8"));
OutputStream os = new BufferedOutputStream(new FileOutputStream(file), BUFFER);
try {
Algorithms.streamCopy(inputStream, os);
} finally {
Algorithms.closeStream(inputStream);
Algorithms.closeStream(os);
} }
json.put("items", itemsJson); }
private void saveZipItems(File file, JSONObject json) throws JSONException, IOException {
OutputStream os = new BufferedOutputStream(new FileOutputStream(file), BUFFER); OutputStream os = new BufferedOutputStream(new FileOutputStream(file), BUFFER);
ZipOutputStream zos = new ZipOutputStream(os); ZipOutputStream zos = new ZipOutputStream(os);
try { try {
@ -1982,6 +2022,20 @@ public class SettingsHelper {
Algorithms.closeStream(os); Algorithms.closeStream(os);
} }
} }
private JSONObject createItemsJson() throws JSONException {
JSONObject json = new JSONObject();
json.put("version", VERSION);
for (Map.Entry<String, String> param : additionalParams.entrySet()) {
json.put(param.getKey(), param.getValue());
}
JSONArray itemsJson = new JSONArray();
for (SettingsItem item : items.values()) {
itemsJson.put(new JSONObject(item.toJson()));
}
json.put("items", itemsJson);
return json;
}
} }
private static class SettingsImporter { private static class SettingsImporter {
@ -2326,10 +2380,10 @@ public class SettingsHelper {
ExportAsyncTask(@NonNull File settingsFile, ExportAsyncTask(@NonNull File settingsFile,
@Nullable SettingsExportListener listener, @Nullable SettingsExportListener listener,
@NonNull List<SettingsItem> items) { @NonNull List<SettingsItem> items, boolean onlyJson) {
this.file = settingsFile; this.file = settingsFile;
this.listener = listener; this.listener = listener;
this.exporter = new SettingsExporter(); this.exporter = new SettingsExporter(onlyJson);
for (SettingsItem item : items) { for (SettingsItem item : items) {
exporter.addSettingsItem(item); exporter.addSettingsItem(item);
} }
@ -2372,7 +2426,14 @@ public class SettingsHelper {
public void exportSettings(@NonNull File fileDir, @NonNull String fileName, @Nullable SettingsExportListener listener, @NonNull List<SettingsItem> items) { public void exportSettings(@NonNull File fileDir, @NonNull String fileName, @Nullable SettingsExportListener listener, @NonNull List<SettingsItem> items) {
File file = new File(fileDir, fileName + OSMAND_SETTINGS_FILE_EXT); File file = new File(fileDir, fileName + OSMAND_SETTINGS_FILE_EXT);
ExportAsyncTask exportAsyncTask = new ExportAsyncTask(file, listener, items); ExportAsyncTask exportAsyncTask = new ExportAsyncTask(file, listener, items, false);
exportAsyncTasks.put(file, exportAsyncTask);
exportAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void exportPluginItems(@NonNull File pluginDir, @Nullable SettingsExportListener listener, @NonNull List<SettingsItem> items) {
File file = new File(pluginDir, "items.json");
ExportAsyncTask exportAsyncTask = new ExportAsyncTask(file, listener, items, true);
exportAsyncTasks.put(file, exportAsyncTask); exportAsyncTasks.put(file, exportAsyncTask);
exportAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); exportAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }

View file

@ -41,14 +41,16 @@ import net.osmand.data.FavouritePoint;
import net.osmand.plus.AppInitializer; import net.osmand.plus.AppInitializer;
import net.osmand.plus.AppInitializer.AppInitializeListener; import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.AppInitializer.InitEvents;
import net.osmand.plus.CustomOsmandPlugin;
import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.GPXDatabase; import net.osmand.plus.GPXDatabase;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper; import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.PluginSettingsItem;
import net.osmand.plus.SettingsHelper.SettingsCollectListener; import net.osmand.plus.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.SettingsHelper.SettingsImportListener;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.ActivityResultListener; import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
@ -746,7 +748,7 @@ public class ImportHelper {
} }
} }
private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject<List<SettingsHelper.SettingsItem>> callback) { private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject<List<SettingsItem>> callback) {
if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) { if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) {
int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1); int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1);
String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY); String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY);
@ -758,7 +760,7 @@ public class ImportHelper {
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version, private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version,
final CallbackWithObject<List<SettingsHelper.SettingsItem>> callback) { final CallbackWithObject<List<SettingsItem>> callback) {
final AsyncTask<Void, Void, String> settingsImportTask = new AsyncTask<Void, Void, String>() { final AsyncTask<Void, Void, String> settingsImportTask = new AsyncTask<Void, Void, String>() {
ProgressDialog progress; ProgressDialog progress;
@ -787,45 +789,22 @@ public class ImportHelper {
if (error == null && file.exists()) { if (error == null && file.exists()) {
app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() {
@Override @Override
public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) { public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items) {
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss(); progress.dismiss();
} }
if (succeed) { if (succeed) {
List<SettingsHelper.SettingsItem> pluginIndependentItems = new ArrayList<>(); List<SettingsItem> pluginIndependentItems = new ArrayList<>();
List<SettingsHelper.PluginSettingsItem> pluginSettingsItems = new ArrayList<>(); List<PluginSettingsItem> pluginSettingsItems = new ArrayList<>();
for (SettingsHelper.SettingsItem item : items) { for (SettingsItem item : items) {
if (item instanceof SettingsHelper.PluginSettingsItem) { if (item instanceof PluginSettingsItem) {
pluginSettingsItems.add((SettingsHelper.PluginSettingsItem) item); pluginSettingsItems.add((PluginSettingsItem) item);
} else if (Algorithms.isEmpty(item.getPluginId())) { } else if (Algorithms.isEmpty(item.getPluginId())) {
pluginIndependentItems.add(item); pluginIndependentItems.add(item);
} }
} }
for (SettingsHelper.PluginSettingsItem pluginItem : pluginSettingsItems) { for (PluginSettingsItem pluginItem : pluginSettingsItems) {
CustomOsmandPlugin plugin = pluginItem.getPlugin(); handlePluginImport(pluginItem, file);
List<SettingsHelper.SettingsItem> pluginItems = pluginItem.getPluginItems();
if (!Algorithms.isEmpty(pluginItems)) {
for (SettingsHelper.SettingsItem item : pluginItems) {
item.setShouldReplace(true);
if (item instanceof SettingsHelper.FileSettingsItem) {
SettingsHelper.FileSettingsItem fileItem = (SettingsHelper.FileSettingsItem) item;
if (fileItem.getSubtype() == SettingsHelper.FileSettingsItem.FileSubtype.RENDERING_STYLE) {
plugin.rendererNames.add(fileItem.getFileName());
}
if (fileItem.getSubtype() == SettingsHelper.FileSettingsItem.FileSubtype.ROUTING_CONFIG) {
plugin.routerNames.add(fileItem.getFileName());
}
}
}
OsmandPlugin.addCustomPlugin(app, activity, plugin);
app.getSettingsHelper().importSettings(file, pluginItems, "", 1, new SettingsHelper.SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsHelper.SettingsItem> items) {
app.showShortToastMessage(app.getString(R.string.file_imported_successfully, ""));
}
});
}
} }
if (!pluginIndependentItems.isEmpty()) { if (!pluginIndependentItems.isEmpty()) {
FragmentManager fragmentManager = activity.getSupportFragmentManager(); FragmentManager fragmentManager = activity.getSupportFragmentManager();
@ -860,6 +839,24 @@ public class ImportHelper {
} }
} }
private void handlePluginImport(final PluginSettingsItem pluginItem, File file) {
List<SettingsItem> pluginItems = new ArrayList<>(pluginItem.getPluginDependentItems());
pluginItems.add(0, pluginItem);
for (SettingsItem item : pluginItems) {
item.setShouldReplace(true);
}
app.getSettingsHelper().importSettings(file, pluginItems, "", 1, new SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
if (activity != null) {
pluginItem.getPlugin().onInstall(app, activity);
}
File pluginDir = new File(app.getAppPath(null), IndexConstants.PLUGINS_DIR + pluginItem.getPluginId());
app.getSettingsHelper().exportPluginItems(pluginDir, null, items);
}
});
}
private void handleXmlFileImport(final Uri intentUri, final String fileName) { private void handleXmlFileImport(final Uri intentUri, final String fileName) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity); AlertDialog.Builder builder = new AlertDialog.Builder(activity);