From 2550a87a6003c2c7b38defe9cc80435038d67d15 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Thu, 28 Dec 2017 08:22:53 -0500 Subject: [PATCH] JsonConfig: Fix script error '=Module:Data:8 attempt to index ? (a nil value)' on a dozen de.w pages --- 100_core/src/gplx/Bry_.java | 19 +++- 100_core/src/gplx/Keyval_.java | 31 +++++-- 400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_.java | 12 ++- 400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java | 1 + .../scribunto/Jscfg_scrib_lib.java | 62 +++++++++++++ .../scribunto/Jscfg_scrib_lib_tst.java | 55 ++++++++++++ .../jsonConfigs/scribunto/Jscfg_xtn_mgr.java | 25 ++++++ .../scribunto/engines/luaj/Luaj_value_.java | 19 +++- .../engines/luaj/Luaj_value__tst.java | 63 +++++++++++++ .../xtns/scribunto/libs/Scrib_lib_text.java | 9 +- .../libs/Scrib_lib_text__json_util.java | 46 ++++++---- .../libs/Scrib_lib_text__reindex_data.java | 26 ++++++ .../libs/Scrib_lib_text_json_tst.java | 89 ++++++++++++++++--- .../xtns/scribunto/libs/Scrib_lib_title.java | 7 +- .../scribunto/libs/Scrib_lib_title_tst.java | 4 +- 15 files changed, 413 insertions(+), 55 deletions(-) create mode 100644 400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib.java create mode 100644 400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib_tst.java create mode 100644 400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_xtn_mgr.java create mode 100644 400_xowa/src/gplx/xowa/xtns/scribunto/engines/luaj/Luaj_value__tst.java create mode 100644 400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text__reindex_data.java diff --git a/100_core/src/gplx/Bry_.java b/100_core/src/gplx/Bry_.java index 4c95a28ab..73c2b423e 100644 --- a/100_core/src/gplx/Bry_.java +++ b/100_core/src/gplx/Bry_.java @@ -355,10 +355,21 @@ public class Bry_ { public static byte[] Mid_safe(byte[] src, int bgn, int end) { if (src == null) return null; int src_len = src.length; - if (bgn < 0) bgn = 0; - if (end >= src_len) end = src_len; - if (bgn > end) bgn = end; - else if (end < bgn) end = bgn; + if (bgn < 0) + bgn = 0; + else if (bgn >= src_len) + bgn = src_len; + + if (end < 0) + end = 0; + else if (end >= src_len) + end = src_len; + + if (bgn > end) + bgn = end; + else if (end < bgn) + end = bgn; + return Mid(src, bgn, end); } public static byte[] Mid(byte[] src, int bgn) {return Mid(src, bgn, src.length);} diff --git a/100_core/src/gplx/Keyval_.java b/100_core/src/gplx/Keyval_.java index 9eecc4124..49bb15546 100644 --- a/100_core/src/gplx/Keyval_.java +++ b/100_core/src/gplx/Keyval_.java @@ -67,24 +67,37 @@ public class Keyval_ { } public static String Ary__to_str__nest(Keyval... ary) { Bry_bfr bfr = Bry_bfr_.New(); - Ary__to_str__nest(bfr, 0, ary); + Ary__to_str__nest__obj(bfr, 0, true, ary); return bfr.To_str_and_clear(); } - private static void Ary__to_str__nest(Bry_bfr bfr, int indent, Keyval[] ary) { + private static void Ary__to_str__nest__obj(Bry_bfr bfr, int indent, boolean is_kv, Object[] ary) { int len = ary.length; for (int i = 0; i < len; ++i) { - Keyval itm = ary[i]; + Object val = ary[i]; if (indent > 0) - bfr.Add_byte_repeat(Byte_ascii.Space, indent * 2); // add indent : " " - bfr.Add_str_u8(Object_.Xto_str_strict_or_empty(itm.Key())).Add_byte_eq();// add key + eq : "key=" - Object val = itm.Val(); + bfr.Add_byte_repeat(Byte_ascii.Space, indent * 2); // add indent; EX: " " + String key = null; + if (is_kv) { + Keyval kv = (Keyval)val; + key = Object_.Xto_str_strict_or_empty(kv.Key()); + val = kv.Val(); + } + else { + key = Int_.To_str(i + 1); + } + bfr.Add_str_u8(key).Add_byte_eq(); // add key + eq : "key=" if (val == null) bfr.Add_str_a7(String_.Null_mark); else { Class val_type = Type_.Type_by_obj(val); - if (Type_.Eq(val_type, Keyval[].class)) { // val is Keyval[]; recurse + if (Type_.Eq(val_type, Keyval[].class)) { // val is Keyval[]; recurse bfr.Add_byte_nl(); // add nl : "\n" - Ary__to_str__nest(bfr, indent + 1, (Keyval[])val); + Ary__to_str__nest__obj(bfr, indent + 1, true, (Keyval[])val); + continue; // don't add \n below + } + else if (Type_.Eq(val_type, Object[].class)) { // val is Object[] + bfr.Add_byte_nl(); + Ary__to_str__nest__obj(bfr, indent + 1, false, (Object[])val); continue; // don't add \n below } else if (Type_.Eq(val_type, Bool_.Cls_ref_type)) { // val is boolean @@ -92,7 +105,7 @@ public class Keyval_ { bfr.Add(val_as_bool ? Bool_.True_bry : Bool_.False_bry); // add "true" or "false"; don't call toString } else - bfr.Add_str_u8(Object_.Xto_str_strict_or_null_mark(val)); // call toString() + bfr.Add_str_u8(Object_.Xto_str_strict_or_null_mark(val)); // call toString() } bfr.Add_byte_nl(); } diff --git a/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_.java b/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_.java index 2d2002339..ba04c62cd 100644 --- a/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_.java +++ b/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_.java @@ -27,6 +27,8 @@ public class Xow_ns_ { , Tid__help = 12 , Tid__help_talk = 13 , Tid__category = 14 , Tid__category_talk = 15 , Tid__portal = 100 , Tid__portal_talk = 101 + , Tid__config = 482 , Tid__config_talk = 483 + , Tid__data = 486 , Tid__data_talk = 487 , Tid__module = 828 , Tid__module_talk = 829 , Tid__null = Int_.Min_value ; @@ -42,11 +44,13 @@ public class Xow_ns_ { , Key__help = "Help" , Key__help_talk = "Help_talk" , Key__category = "Category" , Key__category_talk = "Category_talk" , Key__portal = "Portal" , Key__portal_talk = "Portal_talk" + , Key__config = "Config" , Key__config_talk = "Config_talk" + , Key__data = "Data" , Key__data_talk = "Data_talk" , Key__module = "Module" , Key__module_talk = "Module_talk" , Key__null = "null" , Key__wikipedia = "Wikipedia" ; - public static final byte[] + public static final byte[] Bry__media = Bry_.new_a7(Key__media) , Bry__special = Bry_.new_a7(Key__special) , Bry__main = Bry_.new_a7(Key__main) , Bry__talk = Bry_.new_a7(Key__talk) @@ -58,6 +62,8 @@ public class Xow_ns_ { , Bry__help = Bry_.new_a7(Key__help) , Bry__help_talk = Bry_.new_a7(Key__help_talk) , Bry__category = Bry_.new_a7(Key__category) , Bry__category_talk = Bry_.new_a7(Key__category_talk) , Bry__portal = Bry_.new_a7(Key__portal) , Bry__portal_talk = Bry_.new_a7(Key__portal_talk) + , Bry__config = Bry_.new_a7(Key__config) , Bry__config_talk = Bry_.new_a7(Key__config_talk) + , Bry__data = Bry_.new_a7(Key__data) , Bry__data_talk = Bry_.new_a7(Key__data_talk) , Bry__module = Bry_.new_a7(Key__module) , Bry__module_talk = Bry_.new_a7(Key__module_talk) , Bry__null = Bry_.new_a7(Key__null) ; @@ -65,8 +71,8 @@ public class Xow_ns_ { Alias__wikipedia = "Wikipedia" , Alias__image = "Image" ; - public static final byte[] Alias__image__bry = Bry_.new_a7(Alias__image); - public static final byte[] + public static final byte[] Alias__image__bry = Bry_.new_a7(Alias__image); + public static final byte[] Bry__template_w_colon = Bry_.new_a7(Key__template + ":") , Bry__module_w_colon = Bry_.new_a7(Key__module + ":") ; diff --git a/400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java b/400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java index 25e6b5ae6..3724b33e4 100644 --- a/400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java @@ -46,6 +46,7 @@ public class Xow_xtn_mgr implements Gfo_invk { Add(app, new gplx.xowa.xtns.titleBlacklists.Blacklist_xtn_mgr()); Add(app, new gplx.xowa.xtns.pfuncs.scribunto.Pfunc_xtn_mgr()); Add(app, new gplx.xowa.xtns.flaggedRevs.Flagged_revs_xtn_mgr()); + Add(app, new gplx.xowa.xtns.jsonConfigs.scribunto.Jscfg_xtn_mgr()); return this; } public Xow_xtn_mgr Ctor_by_wiki(Xowe_wiki wiki) { diff --git a/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib.java b/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib.java new file mode 100644 index 000000000..efec50c1d --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib.java @@ -0,0 +1,62 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.jsonConfigs.scribunto; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.jsonConfigs.*; +import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.scribunto.libs.*; import gplx.xowa.xtns.scribunto.procs.*; +import gplx.xowa.wikis.domains.*; +public class Jscfg_scrib_lib implements Scrib_lib { + private final Scrib_lib_text__json_util json_util = new Scrib_lib_text__json_util(); + private Scrib_core core; + public Scrib_lua_mod Mod() {return mod;} private Scrib_lua_mod mod; + public Scrib_lib Init() {procs.Init_by_lib(this, Proc_names); return this;} + public void Core_(Scrib_core v) {this.core = v;} // TEST: + public Scrib_lib Clone_lib(Scrib_core core) {return new Jscfg_scrib_lib();} + public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { + this.core = core; + Init(); + mod = core.RegisterInterface(this, core.App().Fsys_mgr().Bin_xtns_dir().GenSubFil_nest("JsonConfig", "JCLuaLibrary.lua")); + return mod; + } + public Scrib_proc_mgr Procs() {return procs;} private Scrib_proc_mgr procs = new Scrib_proc_mgr(); + public boolean Procs_exec(int key, Scrib_proc_args args, Scrib_proc_rslt rslt) { + switch (key) { + case Proc_get: return Get(args, rslt); + default: throw Err_.new_unhandled(key); + } + } + private static final int Proc_get = 0; + public static final String Invk_get = "get"; + private static final String[] Proc_names = String_.Ary(Invk_get); + public boolean Get(Scrib_proc_args args, Scrib_proc_rslt rslt) { + byte[] ttl_bry = args.Xstr_bry_or_null(0); + + // get commons wiki + Xowe_wiki commons_wiki = (Xowe_wiki)core.App().Wiki_mgr().Get_by_or_null(Xow_domain_itm_.Bry__commons); + if (commons_wiki == null) { + Gfo_usr_dlg_.Instance.Warn_many("", "", "jsonConfigs requires commons wiki: ~{0}", ttl_bry); + return rslt.Init_many_empty(); + } + commons_wiki.Init_assert(); + + // get page + byte[] ttl_in_data_ns = Bry_.Add(gplx.xowa.wikis.nss.Xow_ns_.Bry__data, Byte_ascii.Colon_bry, ttl_bry); + byte[] page = Scrib_lib_title.GetContentInternal(core, commons_wiki, ttl_in_data_ns); + if (page == null) { + throw Err_.new_wo_type("bad argument #1 to 'get' (not a valid title) " + String_.new_u8(ttl_bry)); + } + + return Scrib_lib_text.JsonDecodeStatic(args, rslt, core, json_util, page, Scrib_lib_text__json_util.Opt__force_assoc, Scrib_lib_text__json_util.Flag__none); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib_tst.java b/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib_tst.java new file mode 100644 index 000000000..a6ef7a2c6 --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib_tst.java @@ -0,0 +1,55 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.jsonConfigs.scribunto; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.jsonConfigs.*; +import org.junit.*; +import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.scribunto.libs.*; +public class Jscfg_scrib_lib_tst { + @Before public void init() { + fxt.Clear_for_lib(); + lib = new Jscfg_scrib_lib(); + lib.Init(); + lib.Core_(fxt.Core()); + } private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Jscfg_scrib_lib lib; + @Test public void Get() { + Xowe_wiki commons_wiki = fxt.Parser_fxt().Wiki().Appe().Wiki_mgr().Get_by_or_make(gplx.xowa.wikis.domains.Xow_domain_itm_.Bry__commons).Init_assert(); + fxt.Parser_fxt().Init_page_create(commons_wiki, "Data:Test.tab", gplx.langs.jsons.Json_doc.Make_str_by_apos + ( "{" + , " 'data':" + , " [" + , " [" + , " 'Q1'" + , " , 'Data:Q1'" + , " ]" + , " ," + , " [" + , " 'Q2'" + , " , 'Data:Q2'" + , " ]" + , " ]" + , "}" + )); + fxt.Test_scrib_proc_str_ary(lib, Jscfg_scrib_lib.Invk_get, Keyval_.Ary(Keyval_.int_(1, "Test.tab")), String_.Concat_lines_nl_skip_last + ( "1=" + , " data=" + , " 1=" + , " 1=Q1" + , " 2=Data:Q1" + , " 2=" + , " 1=Q2" + , " 2=Data:Q2" + )); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_xtn_mgr.java b/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_xtn_mgr.java new file mode 100644 index 000000000..ed267c274 --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_xtn_mgr.java @@ -0,0 +1,25 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.jsonConfigs.scribunto; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.jsonConfigs.*; +import gplx.xowa.xtns.scribunto.*; +public class Jscfg_xtn_mgr extends Xox_mgr_base { + @Override public byte[] Xtn_key() {return XTN_KEY;} public static final byte[] XTN_KEY = Bry_.new_a7("JsonConfig"); + @Override public void Xtn_init_by_wiki(Xowe_wiki wiki) { + Scrib_xtn_mgr scrib_xtn = (Scrib_xtn_mgr)wiki.Xtn_mgr().Get_or_fail(Scrib_xtn_mgr.XTN_KEY); + scrib_xtn.Lib_mgr().Add(new Jscfg_scrib_lib()); + } + @Override public Xox_mgr Xtn_clone_new() {return new Jscfg_xtn_mgr();} +} diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/engines/luaj/Luaj_value_.java b/400_xowa/src/gplx/xowa/xtns/scribunto/engines/luaj/Luaj_value_.java index 113abd750..bae707f2d 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/engines/luaj/Luaj_value_.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/engines/luaj/Luaj_value_.java @@ -122,17 +122,18 @@ class Luaj_value_ { else if (Object_.Eq(c, String_.Cls_ref_type)) return LuaValue.valueOf((String)o); else if (Object_.Eq(c, Double_.Cls_ref_type)) return LuaValue.valueOf((Double)o); else if (Object_.Eq(c, byte[].class)) return LuaValue.valueOf(String_.new_u8((byte[])o)); - else if (Object_.Eq(c, Keyval.class)) return Kv_ary_to_lua_tbl(server, (Keyval)o); - else if (Object_.Eq(c, Keyval[].class)) return Kv_ary_to_lua_tbl(server, (Keyval[])o); + else if (Object_.Eq(c, Keyval.class)) return Make_lua_tbl_by_kv_ary(server, (Keyval)o); + else if (Object_.Eq(c, Keyval[].class)) return Make_lua_tbl_by_kv_ary(server, (Keyval[])o); + else if (Object_.Eq(c, Object[].class)) return Make_lua_tbl_by_obj_ary(server, ((Object[])o)); // PAGE:de.w:Reicholzheim DATE:2017-12-25 else if (Object_.Eq(c, Long_.Cls_ref_type)) return LuaValue.valueOf((Long)o); else if (Object_.Eq(c, Scrib_lua_proc.class)) return server.Get_closure_by_id(((Scrib_lua_proc)o).Id()); else if (Object_.Eq(c, Float_.Cls_ref_type)) return LuaValue.valueOf((Float)o); else if (Object_.Eq(c, Char_.Cls_ref_type)) return LuaValue.valueOf((Character)o); else if (Object_.Eq(c, Short_.Cls_ref_type)) return LuaValue.valueOf((Short)o); else if (Object_.Eq(c, Decimal_adp.class)) return LuaValue.valueOf(((Decimal_adp)o).To_double()); // DATE:2016-08-01 - else return LuaValue.NIL; + else return LuaValue.NIL; } - private static LuaTable Kv_ary_to_lua_tbl(Luaj_server server, Keyval... ary) { + private static LuaTable Make_lua_tbl_by_kv_ary(Luaj_server server, Keyval... ary) { LuaTable rv = LuaValue.tableOf(); int len = ary.length; for (int i = 0; i < len; i++) { @@ -150,4 +151,14 @@ class Luaj_value_ { } return rv; } + private static LuaTable Make_lua_tbl_by_obj_ary(Luaj_server server, Object... ary) { + LuaTable rv = LuaValue.tableOf(); + int len = ary.length; + for (int i = 0; i < len; i++) { + Object itm = ary[i]; + LuaValue itm_val = Obj_to_lua_val(server, itm); + rv.set(i + List_adp_.Base1, itm_val); // NOTE: + 1 b/c lua array are 1-based + } + return rv; + } } diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/engines/luaj/Luaj_value__tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/engines/luaj/Luaj_value__tst.java new file mode 100644 index 000000000..7e4e34e5c --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/engines/luaj/Luaj_value__tst.java @@ -0,0 +1,63 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.scribunto.engines.luaj; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.scribunto.engines.*; +import org.junit.*; +import gplx.core.tests.*; +import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; +public class Luaj_value__tst { + private static final Luaj_value__fxt fxt = new Luaj_value__fxt(); + @Test public void Obj_to_lua_val() { + fxt.Test__Obj_to_lua_val + ( Keyval_.Ary + ( Keyval_.new_("data", Object_.Ary + ( Keyval_.Ary + ( Keyval_.new_("type", "type1") + , Keyval_.new_("name", "name1") + ) + , Keyval_.Ary + ( Keyval_.new_("type", "type2") + , Keyval_.new_("name", "name2") + ) + ) + ) + ), String_.Concat_lines_nl_skip_last + ( "data=" + , " 1=" + , " name=name1" + , " type=type1" + , " 2=" + , " name=name2" + , " type=type2" + )); + } + } +class Luaj_value__fxt { + public void Test__Obj_to_lua_val(Object val, String expd) { + Luaj_server server = null; + LuaValue actl_lv = Luaj_value_.Obj_to_lua_val(server, val); + + String actl = null; + if (actl_lv.istable()) { + Keyval[] actl_kv = Luaj_value_.Lua_tbl_to_kv_ary(server, (LuaTable)actl_lv); + actl = Keyval_.Ary__to_str__nest(actl_kv); + } + else { + actl = actl_lv.tojstring(); + } + Gftest.Eq__ary__lines(expd, actl, "", ""); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text.java index 9fdd0fe01..a0adc4d7d 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text.java @@ -19,7 +19,6 @@ import gplx.xowa.langs.msgs.*; import gplx.xowa.xtns.scribunto.procs.*; public class Scrib_lib_text implements Scrib_lib { private final Scrib_lib_text__json_util json_util = new Scrib_lib_text__json_util(); - private final Scrib_lib_text__reindex_data reindex_data = new Scrib_lib_text__reindex_data(); public Scrib_lib_text(Scrib_core core) {this.core = core;} private Scrib_core core; public Scrib_lua_mod Mod() {return mod;} private Scrib_lua_mod mod; public Scrib_lib Init() {procs.Init_by_lib(this, Proc_names); return this;} @@ -80,6 +79,7 @@ public class Scrib_lib_text implements Scrib_lib { if ( itm_is_nde && !Bitmask_.Has_int(flags, Scrib_lib_text__json_util.Flag__preserve_keys) ) { + Scrib_lib_text__reindex_data reindex_data = new Scrib_lib_text__reindex_data(); json_util.Reindex_arrays(reindex_data, itm_as_nde, true); if (reindex_data.Rv_is_kvy()) { itm_as_nde = reindex_data.Rv_as_kvy(); @@ -108,6 +108,11 @@ public class Scrib_lib_text implements Scrib_lib { if (Bitmask_.Has_int(flags, Scrib_lib_text__json_util.Flag__try_fixing)) opts = Bitmask_.Add_int(opts, Scrib_lib_text__json_util.Flag__try_fixing); + return JsonDecodeStatic(args, rslt, core, json_util, json, opts, flags); + } + public static boolean JsonDecodeStatic + ( Scrib_proc_args args, Scrib_proc_rslt rslt, Scrib_core core, Scrib_lib_text__json_util json_util + , byte[] json, int opts, int flags) { // decode json to Object; note that Bool_.Y means ary and Bool_.N means ary byte rv_tid = json_util.Decode(core.App().Utl__json_parser(), json, opts); if (rv_tid == Bool_.__byte) throw Err_.new_("scribunto", "mw.text.jsonEncode: Unable to decode String " + String_.new_u8(json)); @@ -116,6 +121,7 @@ public class Scrib_lib_text implements Scrib_lib { // reindex unless preserve_keys passed if (!(Bitmask_.Has_int(flags, Scrib_lib_text__json_util.Flag__preserve_keys))) { + Scrib_lib_text__reindex_data reindex_data = new Scrib_lib_text__reindex_data(); json_util.Reindex_arrays(reindex_data, rv_as_kvy, false); rv_as_kvy = reindex_data.Rv_is_kvy() ? (Keyval[])reindex_data.Rv_as_kvy() : (Keyval[])reindex_data.Rv_as_ary(); } @@ -124,6 +130,7 @@ public class Scrib_lib_text implements Scrib_lib { else return rslt.Init_obj(json_util.Decode_rslt_as_ary()); } + public void Notify_wiki_changed() {if (notify_wiki_changed_fnc != null) core.Interpreter().CallFunction(notify_wiki_changed_fnc.Id(), Keyval_.Ary_empty);} public boolean Init_text_for_wiki(Scrib_proc_args args, Scrib_proc_rslt rslt) { Xow_msg_mgr msg_mgr = core.Wiki().Msg_mgr(); diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text__json_util.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text__json_util.java index 827c1cf59..97ccc72ab 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text__json_util.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text__json_util.java @@ -15,7 +15,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt */ package gplx.xowa.xtns.scribunto.libs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*; import gplx.langs.jsons.*; -class Scrib_lib_text__json_util { +public class Scrib_lib_text__json_util { private final Json_wtr wtr = new Json_wtr(); public void Reindex_arrays(Scrib_lib_text__reindex_data rv, Keyval[] kv_ary, boolean is_encoding) { int next = 0; @@ -118,11 +118,37 @@ class Scrib_lib_text__json_util { return rv; } private Object Decode_ary_sub(Json_ary ary) { + boolean subs_are_primitive = true; + + // if ary has sub_ary / sub_nde, then unflag subs_are_primitive int len = ary.Len(); - Object[] rv = new Object[len]; - for (int i = 0; i < len; ++i) { - Json_itm itm = ary.Get_at(i); - rv[i] = Decode_obj(itm); + if (len > 0) { + Json_itm sub = ary.Get_at(0); + switch (sub.Tid()) { + case Json_itm_.Tid__nde: + case Json_itm_.Tid__ary: + subs_are_primitive = false; + break; + } + } + + // generate array + Object[] rv = null; + // if subs_are_primitive, then just generate an Object[] + if (subs_are_primitive) { + rv = new Object[len]; + for (int i = 0; i < len; ++i) { + Json_itm itm = ary.Get_at(i); + rv[i] = Decode_obj(itm); + } + } + // else generate a Keyval where val is ary / nde + else { + rv = new Keyval[len]; + for (int i = 0; i < len; ++i) { + Json_itm itm = ary.Get_at(i); + rv[i] = Keyval_.int_(i, Decode_obj(itm)); + } } return rv; } @@ -209,13 +235,3 @@ class KeyVal__sorter__key_is_numeric implements gplx.core.lists.ComparerAble { } public static final KeyVal__sorter__key_is_numeric Instance = new KeyVal__sorter__key_is_numeric(); KeyVal__sorter__key_is_numeric() {} } -class Scrib_lib_text__reindex_data { - public boolean Rv_is_kvy() {return rv_is_kvy;} private boolean rv_is_kvy; - public Keyval[] Rv_as_kvy() {return rv_as_kvy;} private Keyval[] rv_as_kvy; - public Object Rv_as_ary() {return rv_as_ary;} private Object rv_as_ary; - public void Init(boolean rv_is_kvy, Keyval[] rv_as_kvy, Object rv_as_ary) { - this.rv_is_kvy = rv_is_kvy; - this.rv_as_kvy = rv_as_kvy; - this.rv_as_ary = rv_as_ary; - } -} diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text__reindex_data.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text__reindex_data.java new file mode 100644 index 000000000..333bb3c5b --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text__reindex_data.java @@ -0,0 +1,26 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.scribunto.libs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*; +public class Scrib_lib_text__reindex_data { + public boolean Rv_is_kvy() {return rv_is_kvy;} private boolean rv_is_kvy; + public Keyval[] Rv_as_kvy() {return rv_as_kvy;} private Keyval[] rv_as_kvy; + public Object Rv_as_ary() {return rv_as_ary;} private Object rv_as_ary; + public void Init(boolean rv_is_kvy, Keyval[] rv_as_kvy, Object rv_as_ary) { + this.rv_is_kvy = rv_is_kvy; + this.rv_as_kvy = rv_as_kvy; + this.rv_as_ary = rv_as_ary; + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text_json_tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text_json_tst.java index 0718afbd5..b99fcaa2e 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text_json_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text_json_tst.java @@ -188,29 +188,92 @@ public class Scrib_lib_text_json_tst { , Kv_ary_utl.new_(Bool_.Y, new Object[] {1, 2, 3, new Object[] {4, 5, new Object[] {6, 7, 8}, 9}}) ); } - @Test public void Nde__smoke() { - json_fxt.Test_json_encode(fxt, lib - , Scrib_lib_text__json_util.Flag__none - , Keyval_.Ary - ( Keyval_.new_("axes", Keyval_.Ary - ( Keyval_.int_(1, Keyval_.Ary - ( Keyval_.new_("type", "x") - )) - , Keyval_.int_(2, Keyval_.Ary - ( Keyval_.new_("type", "y") - )) - )) - ) + @Test public void Nested__ary__nde() { + json_fxt.Test_json_roundtrip(fxt, lib , Json_doc.Make_str_by_apos ( "{ 'axes':" , " [" , " { 'type':'x'" + , " , 'name':'X'" , " }" , " , { 'type':'y'" + , " , 'name':'Y'" , " }" , " ]" , "}" ) + , Keyval_.Ary + ( Keyval_.new_("axes", Keyval_.Ary + ( Keyval_.int_(1, Keyval_.Ary + ( Keyval_.new_("type", "x") + , Keyval_.new_("name", "X") + )) + , Keyval_.int_(2, Keyval_.Ary + ( Keyval_.new_("type", "y") + , Keyval_.new_("name", "Y") + )) + )) + ) + ); + } + @Test public void Nested__ary__ary() { + json_fxt.Test_json_roundtrip(fxt, lib + , Json_doc.Make_str_by_apos + ( "{ 'axes':" + , " [ " + , " [ 'a1'" + , " , 'a2'" + , " ]" + , " , " + , " [ 'b1'" + , " , 'b2'" + , " ]" + , " ]" + , "}" + ) + , Keyval_.Ary + ( Keyval_.new_("axes", Keyval_.Ary + ( Keyval_.int_(1, new Object[] + { "a1" + , "a2" + }) + , Keyval_.int_(2, new Object[] + { "b1" + , "b2" + }) + )) + ) + ); + } + @Test public void Nested__ary__ary_nde() { + json_fxt.Test_json_roundtrip(fxt, lib + , Json_doc.Make_str_by_apos + ( "{ 'axes':" + , " [ " + , " [" + , " { 'type':'x1'" + , " , 'name':'X1'" + , " }" + , " , { 'type':'y1'" + , " , 'name':'Y1'" + , " }" + , " ]" + , " ]" + , "}" + ) + , Keyval_.Ary + ( Keyval_.new_("axes", Keyval_.Ary + ( Keyval_.int_(1, Keyval_.Ary + ( Keyval_.int_(1, Keyval_.Ary + ( Keyval_.new_("type", "x1") + , Keyval_.new_("name", "X1") + )) + , Keyval_.int_(2, Keyval_.Ary + ( Keyval_.new_("type", "y1") + , Keyval_.new_("name", "Y1") + )) + )) + ))) ); } @Test public void Decode__key__int() { diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_title.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_title.java index 082963eef..af8cde194 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_title.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_title.java @@ -175,7 +175,7 @@ public class Scrib_lib_title implements Scrib_lib { } private static final Keyval[] GetFileInfo_absent = Keyval_.Ary(Keyval_.new_("exists", false), Keyval_.new_("width", 0), Keyval_.new_("height", 0)); // NOTE: must supply non-null values for w / h, else Modules will fail with nil errors; PAGE:pl.w:Andrespol DATE:2016-08-01 public boolean GetContent(Scrib_proc_args args, Scrib_proc_rslt rslt) { byte[] ttl_bry = args.Pull_bry(0); - byte[] rv = GetContentInternal(ttl_bry); + byte[] rv = GetContentInternal(core, core.Wiki(), ttl_bry); return rv == null ? rslt.Init_obj(null) : rslt.Init_obj(String_.new_u8(rv)); } public boolean GetCurrentTitle(Scrib_proc_args args, Scrib_proc_rslt rslt) { @@ -184,9 +184,8 @@ public class Scrib_lib_title implements Scrib_lib { public boolean ProtectionLevels(Scrib_proc_args args, Scrib_proc_rslt rslt) { return rslt.Init_obj(protectionLevels_dflt); } - private byte[] GetContentInternal(byte[] ttl_bry) { - Xowe_wiki wiki = core.Wiki(); - Xoa_ttl ttl = Xoa_ttl.Parse(wiki, ttl_bry); if (ttl == null) return null; + public static byte[] GetContentInternal(Scrib_core core, Xowe_wiki wiki, byte[] ttl_bry) { + Xoa_ttl ttl = wiki.Ttl_parse(ttl_bry); if (ttl == null) return null; Xow_page_cache_itm page_itm = wiki.Cache_mgr().Page_cache().Get_or_load_as_itm_2(ttl); byte[] rv = null; if (page_itm != null) { diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_title_tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_title_tst.java index 14b4df7fe..6766a5446 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_title_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_title_tst.java @@ -111,13 +111,13 @@ public class Scrib_lib_title_tst { fxt.Test__proc__objs__nest(lib, Scrib_lib_title.Invk_redirectTarget, Object_.Ary("A1") , Scrib_invoke_func_fxt.Null_rslt_ary); } - private static void Wiki_orig_tbl__create(Xowe_wiki wiki) { + public static void Wiki_orig_tbl__create(Xowe_wiki wiki) { Xowe_wiki_.Create(wiki, 1, "dump.xml"); gplx.xowa.wikis.data.Xow_db_file text_db = wiki.Data__core_mgr().Dbs__make_by_tid(gplx.xowa.wikis.data.Xow_db_file_.Tid__text); text_db.Tbl__text().Create_tbl(); gplx.fsdb.Fsdb_db_mgr__v2_bldr.Get_or_make(wiki, Bool_.Y); wiki.File_mgr().Init_file_mgr_by_load(wiki); } - private static void Wiki_orig_tbl__insert(Xowe_wiki wiki, String ttl_str, int w, int h) { + public static void Wiki_orig_tbl__insert(Xowe_wiki wiki, String ttl_str, int w, int h) { byte[] ttl_bry = Bry_.new_u8(ttl_str); wiki.File__orig_mgr().Insert(gplx.xowa.files.repos.Xof_repo_tid_.Tid__remote, ttl_bry, gplx.xowa.files.Xof_ext_.new_by_ttl_(ttl_bry).Id(), w, h, Bry_.Empty); }