From 97b1055b4e00b2f5563bea31a68efb3c1abd079f Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Sat, 20 Jun 2020 17:47:42 -0400 Subject: [PATCH] Scribunto: Add configurable timeout for en.wikipedia.org and 'Authority_control' [#737] --- 400_xowa/src/gplx/langs/jsons/Json_nde.java | 54 +++-- .../src/gplx/langs/jsons/Json_parser.java | 48 +++-- .../src/gplx/xowa/addons/Xoax_addon_mgr.java | 3 + .../cfgs/specials/edits/objs/Xoedit_itm.java | 64 +++--- .../edits/services/Xocfg_edit_loader.java | 62 ++++-- .../addons/apps/settings/CfgResolver.java | 25 +++ .../addons/apps/settings/SettingsAddon.java | 83 ++++++++ .../xowa/wikis/caches/Xow_page_cache.java | 19 +- .../gplx/xowa/xtns/scribunto/Scrib_core.java | 75 +++++-- .../xowa/xtns/scribunto/Scrib_core_mgr.java | 33 ++-- .../xtns/scribunto/Scrib_invoke_func.java | 46 +++-- .../xowa/xtns/scribunto/cfgs/ScribCfg.java | 27 +++ .../xtns/scribunto/cfgs/ScribCfgResolver.java | 76 +++++++ .../scribunto/cfgs/ScribCfgResolverApp.java | 186 ++++++++++++++++++ .../scribunto/cfgs/ScribCfgResolverTest.java | 186 ++++++++++++++++++ res/bin/any/xowa/addon/app/cfg/xo.cfg.sqlite3 | Bin 278528 -> 282624 bytes 16 files changed, 856 insertions(+), 131 deletions(-) create mode 100644 400_xowa/src/gplx/xowa/addons/apps/settings/CfgResolver.java create mode 100644 400_xowa/src/gplx/xowa/addons/apps/settings/SettingsAddon.java create mode 100644 400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfg.java create mode 100644 400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolver.java create mode 100644 400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolverApp.java create mode 100644 400_xowa/tst/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolverTest.java diff --git a/400_xowa/src/gplx/langs/jsons/Json_nde.java b/400_xowa/src/gplx/langs/jsons/Json_nde.java index 4bf9627d3..23a4822f1 100644 --- a/400_xowa/src/gplx/langs/jsons/Json_nde.java +++ b/400_xowa/src/gplx/langs/jsons/Json_nde.java @@ -1,19 +1,33 @@ -/* -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.langs.jsons; import gplx.*; import gplx.langs.*; +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.langs.jsons; + +import gplx.Array_; +import gplx.Bool_; +import gplx.Bry_; +import gplx.Bry_bfr; +import gplx.Byte_ascii; +import gplx.DateAdp; +import gplx.DateAdp_; +import gplx.Err_; +import gplx.Hash_adp_bry; +import gplx.Int_; +import gplx.Long_; +import gplx.String_; + public class Json_nde extends Json_itm_base implements Json_grp { private Json_itm[] subs = Json_itm_.Ary_empty; private int subs_len = 0, subs_max = 0; private Hash_adp_bry subs_hash; @@ -25,6 +39,7 @@ public class Json_nde extends Json_itm_base implements Json_grp { @Override public byte[] Data_bry() {return null;} public int Len() {return subs_len;} public Json_itm Get_at(int i) {return subs[i];} + public Json_itm Get_as_itm_or_null(String key) {return Get_as_itm_or_null(Bry_.new_u8(key));} public Json_itm Get_as_itm_or_null(byte[] key) {if (subs_hash == null) subs_hash = subs_hash_init(); return (Json_itm)subs_hash.Get_by_bry(key);} public Json_ary Get_as_ary(int idx) {return Json_ary.cast(Get_at(idx));} public Json_nde Get_as_nde(String key) {return Json_nde.cast(Get_as_itm_or_null(Bry_.new_u8(key)));} @@ -34,6 +49,13 @@ public class Json_nde extends Json_itm_base implements Json_grp { Json_itm rv = Get_as_itm_or_null(key); if (rv == null) throw Err_.new_("json", "key missing", "key", key); return Json_ary.cast(rv); } + public Json_ary Get_as_ary_or_null(String key) {return Get_as_ary_or_null(Bry_.new_u8(key));} + public Json_ary Get_as_ary_or_null(byte[] key) { + Json_itm rv = Get_as_itm_or_null(key); + return rv == null + ? null + : Json_ary.cast(rv); + } public byte[] Get_as_bry(String key) { byte[] rv = Get_as_bry_or(Bry_.new_u8(key), null); if (rv == null) throw Err_.new_("json", "key missing", "key", key); return rv; diff --git a/400_xowa/src/gplx/langs/jsons/Json_parser.java b/400_xowa/src/gplx/langs/jsons/Json_parser.java index 2cdae2251..fbfd89731 100644 --- a/400_xowa/src/gplx/langs/jsons/Json_parser.java +++ b/400_xowa/src/gplx/langs/jsons/Json_parser.java @@ -1,20 +1,30 @@ -/* -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.langs.jsons; import gplx.*; import gplx.langs.*; -import gplx.core.primitives.*; +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.langs.jsons; + +import gplx.Bool_; +import gplx.Bry_; +import gplx.Byte_ascii; +import gplx.Char_; +import gplx.Err; +import gplx.Err_; +import gplx.Int_; +import gplx.String_; +import gplx.core.primitives.Gfo_number_parser; + public class Json_parser { private byte[] src; private int src_len, pos; private final Gfo_number_parser num_parser = new Gfo_number_parser(); public Json_factory Factory() {return factory;} private final Json_factory factory = new Json_factory(); @@ -181,4 +191,8 @@ public class Json_parser { return Err_.new_wo_type(msg); } private static final byte[] Bry_bool_rue = Bry_.new_a7("rue"), Bry_bool_alse = Bry_.new_a7("alse"), Bry_null_ull = Bry_.new_a7("ull"); + public static Json_doc ParseToJdoc(String src) { + Json_parser parser = new Json_parser(); + return parser.Parse(src); + } } diff --git a/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java b/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java index 1574dcd77..74e2cc92b 100644 --- a/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java @@ -69,6 +69,9 @@ public class Xoax_addon_mgr { , new gplx.xowa.addons.wikis.ctgs.bldrs .Xoax_ctg_bldr_addon() , new gplx.xowa.xtns.wbases.imports .Xowb_bldr_addon() + // app infrastructure + , new gplx.xowa.addons.apps.settings .SettingsAddon() + // xtns , new gplx.xowa.xtns.math .Xomath_addon() , new gplx.xowa.xtns.template_styles .Template_styles_addon() diff --git a/400_xowa/src/gplx/xowa/addons/apps/cfgs/specials/edits/objs/Xoedit_itm.java b/400_xowa/src/gplx/xowa/addons/apps/cfgs/specials/edits/objs/Xoedit_itm.java index 6109264ce..4a8f4a176 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/cfgs/specials/edits/objs/Xoedit_itm.java +++ b/400_xowa/src/gplx/xowa/addons/apps/cfgs/specials/edits/objs/Xoedit_itm.java @@ -1,23 +1,33 @@ -/* -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.addons.apps.cfgs.specials.edits.objs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.cfgs.*; import gplx.xowa.addons.apps.cfgs.specials.*; import gplx.xowa.addons.apps.cfgs.specials.edits.*; -import gplx.langs.mustaches.*; -import gplx.core.gfobjs.*; import gplx.langs.jsons.*; -import gplx.xowa.addons.apps.cfgs.mgrs.types.*; import gplx.xowa.addons.apps.cfgs.enums.*; -import gplx.langs.htmls.*; +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.addons.apps.cfgs.specials.edits.objs; + +import gplx.Bool_; +import gplx.Bry_; +import gplx.Bry_bfr; +import gplx.String_; +import gplx.core.gfobjs.Gfobj_nde; +import gplx.langs.htmls.Gfh_utl; +import gplx.langs.mustaches.Mustache_bfr; +import gplx.langs.mustaches.Mustache_doc_itm; +import gplx.langs.mustaches.Mustache_doc_itm_; +import gplx.xowa.addons.apps.cfgs.Xocfg_mgr; +import gplx.xowa.addons.apps.cfgs.enums.Xoitm_type_enum; +import gplx.xowa.addons.apps.cfgs.mgrs.types.Xocfg_type_mgr; + public class Xoedit_itm implements Xoedit_nde, Mustache_doc_itm { private boolean edited; private String type, html_atrs, html_cls, lang, name, ctx, date; @@ -36,7 +46,7 @@ public class Xoedit_itm implements Xoedit_nde, Mustache_doc_itm { public int Sort() {return sort;} private final int sort; public void Load_by_meta(Bry_bfr tmp_bfr, String type, String dflt_str, String html_atrs, String html_cls) { this.type = type; - this.dflt = Gfh_utl.Escape_html_as_bry(tmp_bfr, Bry_.new_u8(dflt_str), Bool_.N, Bool_.N, Bool_.N, Bool_.Y, Bool_.N); + this.dflt = Escape(tmp_bfr, type, dflt_str); this.html_atrs = html_atrs; this.html_cls = html_cls; } @@ -47,7 +57,7 @@ public class Xoedit_itm implements Xoedit_nde, Mustache_doc_itm { } public void Load_by_data(Bry_bfr tmp_bfr, String ctx, String val_str, String date) { this.ctx = ctx; - this.val = Gfh_utl.Escape_html_as_bry(tmp_bfr, Bry_.new_u8(val_str), Bool_.N, Bool_.N, Bool_.N, Bool_.Y, Bool_.N); + this.val = Escape(tmp_bfr, type, val_str); this.date = date; this.edited = true; if ( String_.Has(html_cls, "read"+"only") @@ -98,4 +108,14 @@ public class Xoedit_itm implements Xoedit_nde, Mustache_doc_itm { if (String_.Eq(k, "edited")) return Mustache_doc_itm_.Ary__bool(edited); return Mustache_doc_itm_.Ary__empty; } + private static byte[] Escape(Bry_bfr tmp_bfr, String type, String val_str) { + // NOTE: do not escape quotes for memo because it uses + boolean escapeQuotes = Xoitm_type_enum.To_uid(type) == Xoitm_type_enum.Tid__memo + ? Bool_.N + : Bool_.Y; + + return Gfh_utl.Escape_html_as_bry(tmp_bfr, Bry_.new_u8(val_str), Bool_.N, Bool_.N, Bool_.N, escapeQuotes, Bool_.N); + } } diff --git a/400_xowa/src/gplx/xowa/addons/apps/cfgs/specials/edits/services/Xocfg_edit_loader.java b/400_xowa/src/gplx/xowa/addons/apps/cfgs/specials/edits/services/Xocfg_edit_loader.java index 60e560faa..5b5835f12 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/cfgs/specials/edits/services/Xocfg_edit_loader.java +++ b/400_xowa/src/gplx/xowa/addons/apps/cfgs/specials/edits/services/Xocfg_edit_loader.java @@ -1,23 +1,45 @@ -/* -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.addons.apps.cfgs.specials.edits.services; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.cfgs.*; import gplx.xowa.addons.apps.cfgs.specials.*; import gplx.xowa.addons.apps.cfgs.specials.edits.*; -import gplx.dbs.*; -import gplx.xowa.addons.apps.cfgs.dbs.*; import gplx.xowa.addons.apps.cfgs.dbs.tbls.*; -import gplx.xowa.addons.apps.cfgs.specials.edits.objs.*; -import gplx.xowa.addons.apps.cfgs.mgrs.*; import gplx.xowa.addons.apps.cfgs.mgrs.dflts.*; import gplx.xowa.addons.apps.cfgs.mgrs.types.*; +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.addons.apps.cfgs.specials.edits.services; + +import gplx.Bry_bfr; +import gplx.Bry_bfr_; +import gplx.Err_; +import gplx.List_adp; +import gplx.List_adp_; +import gplx.Ordered_hash; +import gplx.Ordered_hash_; +import gplx.String_; +import gplx.dbs.Db_rdr; +import gplx.dbs.Db_sql_; +import gplx.xowa.Xoa_app; +import gplx.xowa.addons.apps.cfgs.dbs.Xocfg_db_app; +import gplx.xowa.addons.apps.cfgs.dbs.Xocfg_db_usr; +import gplx.xowa.addons.apps.cfgs.dbs.tbls.Xocfg_grp_row; +import gplx.xowa.addons.apps.cfgs.mgrs.dflts.Xocfg_dflt_mgr; +import gplx.xowa.addons.apps.cfgs.mgrs.types.Xocfg_type_mgr; +import gplx.xowa.addons.apps.cfgs.specials.edits.objs.Xoedit_grp; +import gplx.xowa.addons.apps.cfgs.specials.edits.objs.Xoedit_itm; +import gplx.xowa.addons.apps.cfgs.specials.edits.objs.Xoedit_nav_itm; +import gplx.xowa.addons.apps.cfgs.specials.edits.objs.Xoedit_nav_mgr; +import gplx.xowa.addons.apps.cfgs.specials.edits.objs.Xoedit_nde; +import gplx.xowa.addons.apps.cfgs.specials.edits.objs.Xoedit_nde_hash; +import gplx.xowa.addons.apps.cfgs.specials.edits.objs.Xoedit_root; +import gplx.xowa.addons.apps.cfgs.specials.edits.objs.Xogui_nde_iter; + public class Xocfg_edit_loader { private final Xocfg_db_app db_app; private final Xocfg_db_usr db_usr; diff --git a/400_xowa/src/gplx/xowa/addons/apps/settings/CfgResolver.java b/400_xowa/src/gplx/xowa/addons/apps/settings/CfgResolver.java new file mode 100644 index 000000000..a0f287f14 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/apps/settings/CfgResolver.java @@ -0,0 +1,25 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.addons.apps.settings; + +import gplx.langs.jsons.Json_doc; +import gplx.xowa.Xow_wiki; + +public interface CfgResolver { + String Key(); + void WhenCfgChanged(Json_doc jdoc); + void WhenWikiCreated(Xow_wiki wikii); +} diff --git a/400_xowa/src/gplx/xowa/addons/apps/settings/SettingsAddon.java b/400_xowa/src/gplx/xowa/addons/apps/settings/SettingsAddon.java new file mode 100644 index 000000000..9dbd4ce43 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/apps/settings/SettingsAddon.java @@ -0,0 +1,83 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.addons.apps.settings; + +import gplx.GfoMsg; +import gplx.Gfo_invk; +import gplx.GfsCtx; +import gplx.Ordered_hash; +import gplx.Ordered_hash_; +import gplx.langs.jsons.Json_doc; +import gplx.langs.jsons.Json_parser; +import gplx.objects.errs.Err_; +import gplx.xowa.Xoa_app; +import gplx.xowa.Xow_wiki; +import gplx.xowa.addons.Xoax_addon_itm; +import gplx.xowa.addons.Xoax_addon_itm__init; +import gplx.xowa.xtns.scribunto.cfgs.ScribCfgResolverApp; + +public class SettingsAddon implements Xoax_addon_itm, Xoax_addon_itm__init, Gfo_invk { + private final Ordered_hash hash = Ordered_hash_.New(); + private Json_doc jdoc; + private boolean init = true; + public String Addon__key() {return ADDON_KEY;} public static final String ADDON_KEY = "xowa.app.settings"; + + @Override + public void Init_addon_by_app(Xoa_app app) { + // NOTE: should move to addon_mgr and create a new interface for settings + this.Add(new ScribCfgResolverApp(app)); + } + private void Add(CfgResolver mgr) { + hash.Add(mgr.Key(), mgr); + } + + @Override + public void Init_addon_by_wiki(Xow_wiki wiki) { + if (init) { // NOTE: cannot `init` in `Init_addon_by_app` b/c `Bind_many` will try to load from db, and dbEngine is not set yet + Update(wiki.App().Cfg().Get_str_app_or(CFG_PUBLISH, null)); + } + else { + if (jdoc == null) return; + for (int i = 0; i < hash.Len(); i++) { + CfgResolver resolver = (CfgResolver)hash.Get_at(i); + resolver.WhenWikiCreated(wiki); + } + } + } + private void Update(String json) { + init = false; + if (json == null) return; + this.jdoc = Json_parser.ParseToJdoc(json); + if (jdoc == null) return; + for (int i = 0; i < hash.Len(); i++) { + CfgResolver resolver = (CfgResolver)hash.Get_at(i); + resolver.WhenCfgChanged(jdoc); + } + } + + @Override + public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { + switch (k) { + case CFG_PUBLISH: + Update(m.ReadStrOr("v", null)); + break; + default: + throw Err_.New_unhandled_default(k); + } + return null; + } + private static final String CFG_PUBLISH = "xowa.app.settings.publish"; +} diff --git a/400_xowa/src/gplx/xowa/wikis/caches/Xow_page_cache.java b/400_xowa/src/gplx/xowa/wikis/caches/Xow_page_cache.java index 852aefb92..21b25168d 100644 --- a/400_xowa/src/gplx/xowa/wikis/caches/Xow_page_cache.java +++ b/400_xowa/src/gplx/xowa/wikis/caches/Xow_page_cache.java @@ -1,6 +1,6 @@ /* XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012-2017 gnosygnu@gmail.com +Copyright (C) 2012-2020 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. @@ -13,8 +13,17 @@ 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.wikis.caches; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; -import gplx.core.caches.*; +package gplx.xowa.wikis.caches; + +import gplx.Bool_; +import gplx.Decimal_adp_; +import gplx.Io_mgr; +import gplx.String_; +import gplx.core.caches.Lru_cache; +import gplx.xowa.Xoa_ttl; +import gplx.xowa.Xoae_page; +import gplx.xowa.Xowe_wiki; + public class Xow_page_cache { private final Object thread_lock = new Object(); // NOTE: thread-safety needed for xomp since one page-cache is shared across all wkrs private final Xowe_wiki wiki; @@ -61,11 +70,11 @@ public class Xow_page_cache { } } public void Free_mem(boolean clear_permanent_itms) { -// synchronized (thread_lock) { // LOCK:app-level; DATE:2016-07-06 + synchronized (thread_lock) { // LOCK:app-level; DATE:2016-07-06 if (clear_permanent_itms) { cache.Clear_all(); } -// } + } } private Xow_page_cache_itm Load_page(Xoa_ttl ttl) { // vars diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core.java index fa0a1b752..2e9331d43 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core.java @@ -1,24 +1,57 @@ -/* -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; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; -import gplx.core.envs.*; -import gplx.xowa.langs.*; -import gplx.xowa.xtns.scribunto.libs.*; import gplx.xowa.xtns.scribunto.engines.*; -import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; -import gplx.xowa.xtns.scribunto.procs.*; +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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; + +import gplx.Bry_; +import gplx.Bry_bfr; +import gplx.Err_; +import gplx.Hash_adp_bry; +import gplx.Io_mgr; +import gplx.Io_url; +import gplx.Keyval; +import gplx.Keyval_; +import gplx.Ordered_hash; +import gplx.Ordered_hash_; +import gplx.String_; +import gplx.core.envs.Env_; +import gplx.xowa.Xoae_app; +import gplx.xowa.Xoae_page; +import gplx.xowa.Xow_wiki; +import gplx.xowa.Xowe_wiki; +import gplx.xowa.langs.Xol_lang_itm; +import gplx.xowa.parsers.Xop_ctx; +import gplx.xowa.parsers.tmpls.Xot_invk; +import gplx.xowa.xtns.scribunto.engines.Scrib_engine; +import gplx.xowa.xtns.scribunto.engines.Scrib_engine_type; +import gplx.xowa.xtns.scribunto.cfgs.ScribCfgResolver; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_hash; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_html; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_language; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_message; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_mw; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_site; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_text; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_title; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_uri; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_ustring; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_wikibase; +import gplx.xowa.xtns.scribunto.libs.Scrib_lib_wikibase_entity; +import gplx.xowa.xtns.scribunto.procs.Scrib_proc; +import gplx.xowa.xtns.scribunto.procs.Scrib_proc_mgr; + public class Scrib_core { private Hash_adp_bry mods = Hash_adp_bry.cs(); private int expensive_function_count; diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core_mgr.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core_mgr.java index 3438328b7..f73736552 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core_mgr.java @@ -1,24 +1,27 @@ -/* -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 -*/ +/* +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; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.wikis.*; import gplx.xowa.parsers.*; +import gplx.xowa.xtns.scribunto.cfgs.ScribCfgResolver; + public class Scrib_core_mgr { public Scrib_core Core() {return core;} private Scrib_core core; public void Terminate_when_page_changes_y_() {terminate_when_page_changes = true;} private boolean terminate_when_page_changes; + public ScribCfgResolver CfgResolver() {return cfgResolver;} public void CfgResolverSet(ScribCfgResolver v) {this.cfgResolver = v;} private ScribCfgResolver cfgResolver; public Scrib_core Core_init(Xop_ctx ctx) { core = new Scrib_core(ctx.App(), ctx); terminate_when_page_changes = false; diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func.java index e74df8ee9..addc80578 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func.java @@ -24,6 +24,8 @@ import gplx.xowa.wikis.nss.*; import gplx.xowa.htmls.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.logs.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.xtns.pfuncs.*; +import gplx.xowa.xtns.scribunto.cfgs.ScribCfg; +import gplx.xowa.xtns.scribunto.cfgs.ScribCfgResolver; public class Scrib_invoke_func extends Pf_func_base { @Override public int Id() {return Xol_kwd_grp_.Id_invoke;} @@ -63,24 +65,38 @@ public class Scrib_invoke_func extends Pf_func_base { if (!core.Enabled()) {bfr.Add_mid(src, self.Src_bgn(), self.Src_end()); return;} try { -// core.Invoke(wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name); -// if (invoke_wkr != null) -// invoke_wkr.Eval_end(ctx.Page(), mod_name, fnc_name, log_time_bgn); + if (String_.Eq(String_.new_u8(mod_name), "Authority control")) { + Tfds.Write(String_.new_u8(ctx.Page().Ttl().Page_db()), String_.new_u8(mod_name), String_.new_u8(fnc_name)); + } + // check if configured for threaded execution + boolean exec = true; + ScribCfgResolver resolver = wiki.Parser_mgr().Scrib().CfgResolver(); + if (resolver != null) { + ScribCfg cfg = resolver.Resolve(ctx.Page().Ttl().Page_db(), Xoa_ttl.Replace_spaces(mod_name), fnc_name); + if (cfg != null) { + if (cfg.TimeoutInMs() != 0) { + exec = false; + int timeoutInMs = cfg.TimeoutInMs(); + long timeBgn = System_.Ticks(); - int timeoutInMs = 5000; - long timeBgn = System_.Ticks(); - - InvokeInvoker invoker = new InvokeInvoker(core, wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name); - Thread_adp thread = Thread_adp_.Start_by_key("scribunto", invoker, "default"); - while (thread.Thread__is_alive()) { - Thread_adp_.Sleep(10); - if (System_.Ticks__elapsed_in_frac(timeBgn) > timeoutInMs) { - thread.Thread__stop(); - invoker.Exc = Err_.new_wo_type(String_.Format("scribunto timeout: page={0} mod={1} func={2} time={3}", ctx.Page_url_str(), mod_name, fnc_name, timeoutInMs)); + InvokeInvoker invoker = new InvokeInvoker(core, wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name); + Thread_adp thread = Thread_adp_.Start_by_key("scribunto", invoker, "default"); + while (thread.Thread__is_alive()) { + Thread_adp_.Sleep(cfg.SleepInMs()); + if (System_.Ticks__elapsed_in_frac(timeBgn) > timeoutInMs) { + thread.Thread__stop(); + invoker.Exc = Err_.new_wo_type(String_.Format("scribunto timeout: page={0} mod={1} func={2} time={3}", ctx.Page_url_str(), mod_name, fnc_name, timeoutInMs)); + } + } + if (invoker.Exc != null) { + throw invoker.Exc; + } + } } } - if (invoker.Exc != null) { - throw invoker.Exc; + // no threaded execution; run sequentially + if (exec) { + core.Invoke(wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name); } if (invoke_wkr != null) invoke_wkr.Eval_end(ctx.Page(), mod_name, fnc_name, log_time_bgn); diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfg.java b/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfg.java new file mode 100644 index 000000000..d0b32615b --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfg.java @@ -0,0 +1,27 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.cfgs; + +public class ScribCfg { + public ScribCfg(int timeoutInMs, int sleepInMs, String regexEngine) { + this.timeoutInMs = timeoutInMs; + this.sleepInMs = sleepInMs; + this.regexEngine = regexEngine; + } + public int TimeoutInMs() {return timeoutInMs;} private int timeoutInMs; + public int SleepInMs() {return sleepInMs;} private int sleepInMs; + public String RegexEngine() {return regexEngine;} private String regexEngine; +} diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolver.java b/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolver.java new file mode 100644 index 000000000..b926371e3 --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolver.java @@ -0,0 +1,76 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.cfgs; + +import gplx.Ordered_hash; +import gplx.String_; +import gplx.langs.jsons.Json_ary; +import gplx.langs.jsons.Json_itm_str; +import gplx.langs.jsons.Json_nde; + +public interface ScribCfgResolver { + String Key(); + ScribCfg Fallback(); void FallbackSet(ScribCfg v); + ScribCfgResolver CloneNew(String key); + void Load(Json_nde owner, ScribCfg ownerFallback); + ScribCfg Resolve(byte[] page, byte[] mod, byte[] func); +} +class ScribCfgResolverUtil { + public static void LoadNode(Json_nde ownerNde, ScribCfg ownerFallback, String subsKey, Ordered_hash hash, ScribCfgResolver self, ScribCfgResolver proto) { + self.FallbackSet(ownerFallback); + Json_ary subsNde = ownerNde.Get_as_ary_or_null(subsKey); + if (subsNde == null) return; + for (int subIdx = 0; subIdx < subsNde.Len(); subIdx++) { + Json_nde subNde = subsNde.Get_at_as_nde(subIdx); + ScribCfg subArgs = ScribCfgResolverUtil.ParseCfgOr(subNde, ownerFallback); + Json_ary subKeys = subNde.Get_as_ary("keys"); + for (int keyIdx = 0; keyIdx < subKeys.Len(); keyIdx++) { + byte[] subKey = subKeys.Get_at(keyIdx).Data_bry(); + ScribCfgResolver subScope = (ScribCfgResolver)hash.Get_by(subKey); + if (subScope == null) { + subScope = proto.CloneNew(String_.new_u8(subKey)); + hash.Add(subKey, subScope); + } + subScope.FallbackSet(subArgs); + subScope.Load(subNde, subArgs); + } + } + } + public static void LoadLeaf(Json_nde ownerNde, ScribCfg ownerFallback, String subsKey, Ordered_hash hash, ScribCfgResolver self) { + self.FallbackSet(ownerFallback); + Json_ary subsNde = ownerNde.Get_as_ary_or_null(subsKey); + if (subsNde == null) return; + for (int idx = 0; idx < subsNde.Len(); idx++) { + Json_nde subNde = subsNde.Get_at_as_nde(idx); + Json_ary subKeys = subNde.Get_as_ary("keys"); + for (int keyIdx = 0; keyIdx < subKeys.Len(); keyIdx++) { + byte[] subKey = ((Json_itm_str)subKeys.Get_at(keyIdx)).Data_bry(); + ScribCfg subArgs = ScribCfgResolverUtil.ParseCfgOr(subNde, ownerFallback); + hash.Add(subKey, subArgs); + } + } + } + public static ScribCfg ParseCfgOr(Json_nde owner, ScribCfg or) { + Json_nde nde = (Json_nde)owner.Get_as_itm_or_null("scribunto"); + if (nde == null) return or; + + int timeout = nde.Get_as_int_or("timeout", 0); + int sleep = nde.Get_as_int_or("sleep", 0); + String regexEngine = nde.Get_as_str_or("regexEngine", "luaj"); + + return new ScribCfg(timeout, sleep, regexEngine); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolverApp.java b/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolverApp.java new file mode 100644 index 000000000..0370da46f --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolverApp.java @@ -0,0 +1,186 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.cfgs; + +import gplx.Err_; +import gplx.Ordered_hash; +import gplx.Ordered_hash_; +import gplx.String_; +import gplx.langs.jsons.Json_doc; +import gplx.langs.jsons.Json_nde; +import gplx.xowa.Xoa_app; +import gplx.xowa.Xow_wiki; +import gplx.xowa.Xowe_wiki; +import gplx.xowa.addons.apps.settings.CfgResolver; + +public class ScribCfgResolverApp implements ScribCfgResolver, CfgResolver { + private final Xoa_app app; + private final Ordered_hash wikis = Ordered_hash_.New_bry(); + private ScribCfg appInvokeArgs; + public ScribCfgResolverApp(Xoa_app app) { + this.app = app; + } + @Override public String Key() {return KEY;} private static final String KEY = "scribCfgResolverApp"; + @Override public ScribCfg Fallback() {return fallback;} @Override public void FallbackSet(ScribCfg v) {fallback = v;} private ScribCfg fallback; + @Override public void WhenWikiCreated(Xow_wiki wikii) { + SetResolverCfg(wikii); + } + @Override public void WhenCfgChanged(Json_doc jdoc) { + Json_nde appNde = jdoc.Root_nde(); + this.appInvokeArgs = ScribCfgResolverUtil.ParseCfgOr(appNde, null); + Load(appNde, appInvokeArgs); + } + @Override public ScribCfg Resolve(byte[] page, byte[] mod, byte[] func) { + throw Err_.new_unimplemented_w_msg("appResolver should not be called; only wikiResolver"); + } + @Override public void Load(Json_nde owner, ScribCfg ownerFallback) { + ScribCfgResolverUtil.LoadNode(owner, ownerFallback, "wikis", wikis, this, ScribCfgResolverWiki.PROTOTYPE); + + // iterate all wikis; needed b/c wiki could get created before Cfg gets fired + for (int i = 0; i < app.Wiki_mgri().Count(); i++) { + Xow_wiki wiki = app.Wiki_mgri().Get_at(i); + SetResolverCfg(wiki); + } + } + private void SetResolverCfg(Xow_wiki wikii) { + Xowe_wiki wiki = (Xowe_wiki)wikii; + byte[] key = wiki.Domain_bry(); + ScribCfgResolverWiki wikiScope = (ScribCfgResolverWiki)wikis.Get_by(key); + if (wikiScope == null) { // no defined cfg; create defailt + wikiScope = new ScribCfgResolverWiki(String_.new_u8(key)); + wikis.Add(key, wikiScope); // cache it for future + } + wiki.Parser_mgr().Scrib().CfgResolverSet(wikiScope); + } + @Override public ScribCfgResolver CloneNew(String key) {return new ScribCfgResolverApp(null);} + public static final ScribCfgResolver PROTOTYPE = new ScribCfgResolverApp(null); +} +class ScribCfgResolverWiki implements ScribCfgResolver { + private final Ordered_hash mods = Ordered_hash_.New_bry(); + private final Ordered_hash pages = Ordered_hash_.New_bry(); + public ScribCfgResolverWiki(String wiki) { + this.key = wiki; + } + @Override public String Key() {return key;} private final String key; + @Override public ScribCfg Fallback() {return fallback;} @Override public void FallbackSet(ScribCfg v) {fallback = v;} private ScribCfg fallback; + @Override public ScribCfg Resolve(byte[] page, byte[] mod, byte[] func) { + ScribCfgResolverModule modResolver = (ScribCfgResolverModule)mods.Get_by(mod); + if (modResolver == null) { + ScribCfgResolverMods pageResolver = (ScribCfgResolverMods)pages.Get_by(mod); + return pageResolver == null + ? fallback + : pageResolver.Resolve(page, mod, func); + } + else { + return modResolver.Resolve(page, mod, func); + } + } + @Override public void Load(Json_nde owner, ScribCfg ownerFallback) { + ScribCfgResolverUtil.LoadNode(owner, ownerFallback, "scribunto.modules", mods, this, ScribCfgResolverModule.PROTOTYPE); + ScribCfgResolverUtil.LoadNode(owner, ownerFallback, "pages", pages, this, ScribCfgResolverMods.PROTOTYPE); + } + @Override public ScribCfgResolver CloneNew(String key) {return new ScribCfgResolverWiki(key);} + public static final ScribCfgResolver PROTOTYPE = new ScribCfgResolverWiki(null); +} +class ScribCfgResolverModule implements ScribCfgResolver { + private final Ordered_hash funcs = Ordered_hash_.New_bry(); + private final Ordered_hash pages = Ordered_hash_.New_bry(); + public ScribCfgResolverModule(String mod) { + this.key = mod; + } + @Override public String Key() {return key;} private final String key; + @Override public ScribCfg Fallback() {return fallback;} @Override public void FallbackSet(ScribCfg v) {fallback = v;} private ScribCfg fallback; + @Override public ScribCfg Resolve(byte[] page, byte[] mod, byte[] func) { + ScribCfgResolverPages funcResolver = (ScribCfgResolverPages)funcs.Get_by(func); + if (funcResolver == null) { + ScribCfgResolverFuncs pageResolver = (ScribCfgResolverFuncs)pages.Get_by(page); + return pageResolver == null + ? fallback + : pageResolver.Resolve(page, mod, func); + } + else { + return funcResolver.Resolve(page, mod, func); + } + } + + @Override public void Load(Json_nde owner, ScribCfg ownerFallback) { + ScribCfgResolverUtil.LoadNode(owner, ownerFallback, "funcs", funcs, this, ScribCfgResolverPages.PROTOTYPE); + ScribCfgResolverUtil.LoadNode(owner, ownerFallback, "pages", pages, this, ScribCfgResolverFuncs.PROTOTYPE); + } + + @Override public ScribCfgResolver CloneNew(String key) {return new ScribCfgResolverModule(key);} + public static final ScribCfgResolver PROTOTYPE = new ScribCfgResolverModule(null); +} +class ScribCfgResolverPages implements ScribCfgResolver { + private final Ordered_hash pages = Ordered_hash_.New_bry(); + public ScribCfgResolverPages(String func) { + this.key = func; + } + @Override public String Key() {return key;} private final String key; + @Override public ScribCfg Fallback() {return fallback;} @Override public void FallbackSet(ScribCfg v) {fallback = v;} private ScribCfg fallback; + @Override public ScribCfg Resolve(byte[] page, byte[] mod, byte[] func) { + ScribCfg rv = (ScribCfg)pages.Get_by(page); + return rv == null + ? fallback + : rv; + } + + @Override public void Load(Json_nde owner, ScribCfg ownerFallback) { + ScribCfgResolverUtil.LoadLeaf(owner, ownerFallback, "pages", pages, this); + } + + @Override public ScribCfgResolver CloneNew(String key) {return new ScribCfgResolverPages(key);} + public static final ScribCfgResolver PROTOTYPE = new ScribCfgResolverPages(null); +} +class ScribCfgResolverMods implements ScribCfgResolver { + private final Ordered_hash mods = Ordered_hash_.New_bry(); + public ScribCfgResolverMods(String page) { + this.key = page; + } + @Override public String Key() {return key;} private final String key; + @Override public ScribCfg Fallback() {return fallback;} @Override public void FallbackSet(ScribCfg v) {fallback = v;} private ScribCfg fallback; + @Override public ScribCfg Resolve(byte[] page, byte[] mod, byte[] func) { + ScribCfgResolverFuncs rv = (ScribCfgResolverFuncs)mods.Get_by(mod); + return rv == null + ? fallback + : rv.Resolve(page, mod, func); + } + @Override public void Load(Json_nde owner, ScribCfg ownerFallback) { + ScribCfgResolverUtil.LoadNode(owner, ownerFallback, "scribunto.modules", mods, this, ScribCfgResolverFuncs.PROTOTYPE); + } + @Override public ScribCfgResolver CloneNew(String key) {return new ScribCfgResolverMods(key);} + public static final ScribCfgResolver PROTOTYPE = new ScribCfgResolverMods(null); +} +class ScribCfgResolverFuncs implements ScribCfgResolver { + private final Ordered_hash funcs = Ordered_hash_.New_bry(); + public ScribCfgResolverFuncs(String key) { + this.key = key; + } + @Override public String Key() {return key;} private final String key; + @Override public ScribCfg Fallback() {return fallback;} @Override public void FallbackSet(ScribCfg v) {fallback = v;} private ScribCfg fallback; + @Override public ScribCfg Resolve(byte[] page, byte[] mod, byte[] func) { + ScribCfg rv = (ScribCfg)funcs.Get_by(func); + return rv == null + ? fallback + : rv; + } + @Override public void Load(Json_nde owner, ScribCfg ownerFallback) { + ScribCfgResolverUtil.LoadLeaf(owner, ownerFallback, "funcs", funcs, this); + } + + @Override public ScribCfgResolver CloneNew(String key) {return new ScribCfgResolverFuncs(key);} + public static final ScribCfgResolver PROTOTYPE = new ScribCfgResolverFuncs(null); +} diff --git a/400_xowa/tst/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolverTest.java b/400_xowa/tst/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolverTest.java new file mode 100644 index 000000000..34a64733c --- /dev/null +++ b/400_xowa/tst/gplx/xowa/xtns/scribunto/cfgs/ScribCfgResolverTest.java @@ -0,0 +1,186 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 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.cfgs; + +import gplx.Bry_; +import gplx.core.tests.Gftest; +import gplx.langs.jsons.Json_doc; +import gplx.langs.jsons.Json_parser; +import org.junit.Test; + +public class ScribCfgResolverTest { + private final ScribCfgResolverTstr tstr = new ScribCfgResolverTstr(); + + @Test public void Pages() { + ScribCfgResolver resolver = tstr.Init(ScribCfgResolverPages.PROTOTYPE, "fallback" + , "{ 'pages':" + , " [" + , " { 'keys':['p1', 'p2']" + , " , 'scribunto.invoke':{'regexEngine':'p1re'}" + , " }" + , " , { 'keys':['p3']" + , " , 'scribunto.invoke':{'regexEngine':'p3re'}" + , " }" + , " ]" + , "}" + ); + tstr.TestResolve(resolver, "p1", null, null, "p1re"); + tstr.TestResolve(resolver, "p2", null, null, "p1re"); + tstr.TestResolve(resolver, "p3", null, null, "p3re"); + tstr.TestResolve(resolver, "z", null, null, "fallback"); + } + + @Test public void Funcs() { + ScribCfgResolver resolver = tstr.Init(ScribCfgResolverFuncs.PROTOTYPE, "fallback" + , "{ 'funcs':" + , " [" + , " { 'keys':['f1', 'f2']" + , " , 'scribunto.invoke':{'regexEngine':'f1re'}" + , " }" + , " , { 'keys':['f3']" + , " , 'scribunto.invoke':{'regexEngine':'f3re'}" + , " }" + , " ]" + , "}" + ); + tstr.TestResolve(resolver, null, null, "f1", "f1re"); + tstr.TestResolve(resolver, null, null, "f2", "f1re"); + tstr.TestResolve(resolver, null, null, "f3", "f3re"); + tstr.TestResolve(resolver, null, null, "z", "fallback"); + } + + @Test public void Module() { + ScribCfgResolver resolver = tstr.Init(ScribCfgResolverModule.PROTOTYPE, "fallback" + , "{ 'funcs':" + , " [" + , " { 'keys':['f1', 'f2']" + , " , 'scribunto.invoke':{'regexEngine':'f1re'}" + , " }" + , " ]" + , ", 'pages':" + , " [" + , " { 'keys':['p1', 'p2']" + , " , 'scribunto.invoke':{'regexEngine':'p1re'}" + , " }" + , " ]" + , "}" + ); + tstr.TestResolve(resolver, null, null, "f1", "f1re"); + tstr.TestResolve(resolver, null, null, "f2", "f1re"); + tstr.TestResolve(resolver, "p1", null, null, "p1re"); + tstr.TestResolve(resolver, "p2", null, null, "p1re"); + tstr.TestResolve(resolver, "pz", null, "fz", "fallback"); + } + + @Test public void Wiki() { + ScribCfgResolver resolver = tstr.Init(ScribCfgResolverWiki.PROTOTYPE, "fallback" + , "{ 'scribunto.modules':" + , " [" + , " { 'keys':['m1', 'm2']" + , " , 'scribunto.invoke':{'regexEngine':'m1re'}" + , " , 'funcs':" + , " [" + , " { 'keys':['f1', 'f2']" + , " , 'scribunto.invoke':{'regexEngine':'m1f1re'}" + , " }" + , " ]" + , " , 'pages':" + , " [" + , " { 'keys':['p1', 'p2']" + , " , 'scribunto.invoke':{'regexEngine':'m1p1re'}" + , " }" + , " ]" + , " }" + , " , { 'keys':['m3']" + , " , 'scribunto.invoke':{'regexEngine':'m3re'}" + , " , 'funcs':" + , " [" + , " { 'keys':['f1', 'f2']" + , " , 'scribunto.invoke':{'regexEngine':'m3f1re'}" + , " }" + , " ]" + , " , 'pages':" + , " [" + , " { 'keys':['p1', 'p2']" + , " , 'scribunto.invoke':{'regexEngine':'m3p1re'}" + , " }" + , " ]" + , " }" + , " ]" + , "}" + ); + tstr.TestResolve(resolver, "p1", "mz", "f1", "fallback"); + tstr.TestResolve(resolver, null, "m1", "f1", "m1f1re"); + tstr.TestResolve(resolver, null, "m1", "f2", "m1f1re"); + tstr.TestResolve(resolver, "p1", "m1", null, "m1p1re"); + tstr.TestResolve(resolver, "p2", "m1", null, "m1p1re"); + tstr.TestResolve(resolver, "pz", "m1", null, "m1re"); + tstr.TestResolve(resolver, null, "m3", "f1", "m3f1re"); + tstr.TestResolve(resolver, null, "m3", "f2", "m3f1re"); + tstr.TestResolve(resolver, "p1", "m3", null, "m3p1re"); + tstr.TestResolve(resolver, "p2", "m3", null, "m3p1re"); + tstr.TestResolve(resolver, "pz", "m3", null, "m3re"); + } + + @Test public void WikiPageScope() { + ScribCfgResolver resolver = tstr.Init(ScribCfgResolverMods.PROTOTYPE, "fallback" + , "{ 'scribunto.modules':" + , " [" + , " { 'keys':['m1', 'm2']" + , " , 'scribunto.invoke':{'regexEngine':'m1re'}" + , " , 'funcs':" + , " [" + , " { 'keys':['f1', 'f2']" + , " , 'scribunto.invoke':{'regexEngine':'m1f1re'}" + , " }" + , " ]" + , " }" + , " ," + , " { 'keys':['m3']" + , " , 'scribunto.invoke':{'regexEngine':'m3re'}" + , " , 'funcs':" + , " [" + , " { 'keys':['f1']" + , " , 'scribunto.invoke':{'regexEngine':'m3f1re'}" + , " }" + , " ]" + , " }" + , " ]" + , "}" + ); + tstr.TestResolve(resolver, null, "mz", null, "fallback"); + tstr.TestResolve(resolver, null, "m1", "f1", "m1f1re"); + tstr.TestResolve(resolver, null, "m2", "f1", "m1f1re"); + tstr.TestResolve(resolver, null, "m1", "fz", "m1re"); + tstr.TestResolve(resolver, null, "m3", "f1", "m3f1re"); + tstr.TestResolve(resolver, null, "m3", "fz", "m3re"); + } +} +class ScribCfgResolverTstr { + public ScribCfgResolver Init(ScribCfgResolver proto, String fallbackRegexEngine, String... jsonAry) { + ScribCfg fallbackArgs = new ScribCfg(1, 2, fallbackRegexEngine); + ScribCfgResolver rv = proto.CloneNew("test"); + + String json = Json_doc.Make_str_by_apos(jsonAry); + Json_doc jdoc = Json_parser.ParseToJdoc(json); + rv.Load(jdoc.Root_nde(), fallbackArgs); + return rv; + } + public void TestResolve(ScribCfgResolver resolver, String page, String mod, String func, String expdRegexEngine) { + ScribCfg actl = resolver.Resolve(Bry_.new_u8_safe(page), Bry_.new_u8_safe(mod), Bry_.new_u8_safe(func)); + Gftest.Eq__str(expdRegexEngine, actl.RegexEngine(), func); + } +} diff --git a/res/bin/any/xowa/addon/app/cfg/xo.cfg.sqlite3 b/res/bin/any/xowa/addon/app/cfg/xo.cfg.sqlite3 index 912054b7a0b5420c0d08f42a8471ebb7b28a8dd0..7c7725f04116462c77266b9de53fd0316b2c0314 100644 GIT binary patch delta 2287 zcmbtWYfKzf6rOu$*xA?2EG@NBD2&sHr76qu=*BDvrGylcKBa2vN_3&)va;+9%Wh~x z+T8{55%7U%wnR;9ViS!fvV}NlG-B0gEfB4`+u&qmI-wz z6V*EDR2!gBmq`V{%!mCiaV%2qAN@W!S)ce0WnY?PlZO~^8!XKnPbR@bWpopr2W}<@ zO7(WSD&Gzi&xmVSa}9%Am5iU7v!<=nU>rJA={Kf9MS5-;ybOiy+TjeSb%+~hP~%*+ zFy@!WyYyD0k6R}_&)uY4M5{E{4TW2-8k36*;|a<-q~>_6M~Q}Fr=RLpBC)6vHlVN@f_o+&>0U#?$~6?c%c?10BDEMm zd&Gnk3lAI&MS8P9aa4All5a?gh5BSA9+P~v9*+kb!?LVOJ}gG%pnR$|5)4J~(S+lH zXQeZGuNVh^kdGP&X0=JwdZ7tZ)>m>yrYaj{&9WidW-YIUVNevh{aio zA*Po2;$5fxj9qKLL3_Db2DmJ|mvUNuO0zDe-32efW#LO9!+2?$_wwFM>JfNs8=5u+ zRAB`tN19bttQ0$paRmRQwj#q0WH41cnp{X#j8q56tYX^ooHTkX(+U_N1J7v(i!U*gC4Ais|<;cjz_+^5`IT$1bIPH^>{#JQYzZ8vSd*sfaNv5sX@ zE!MP~p|_CI(wQCKMQ)5B>jSa0e*q}BJiRJxqC037FMkF6u5Z{P^NJj*nd4`X@ zp-OGE+Z)uV+(;h3353aLIQhwnX_#WAu0za0%R9|P xz0bc2lntg&2&19@SDsO_o(0LB0{W#{Wpy?Az85s(`N82|tPM3Epr0U5Diq(1|I0s@lP7m^tf%*m> z?=%AdLzn$C0~@m=Lg6h49uGSJ0000&lMHY?v4LX&v#W854F^673OsN=Mw2^#$pe4_ z5R(UhO|w{lfB}(^JcAH|w-AB>^eqHh0KW#82(ST+mzJ;rDFOYLzOVs~0t|n*PO$+q z3jzQlm(dOZ6$xZ^Xp}YZO^8vM&1+W51w@|PGB>@48w{)=rD*^$fm!Pu( zm6xE}0ui@Hv;w{h1EL3Ow+FxiMFFva9|pH;#{!uM0~`Xmw+GMyG6I)9(gI?UkRFG* z(gL@+(gR2xQ4W6qB>_nQ0Z9%~4hs#|4WJEZ4HyjD43!LQ3_}a=3!Mu-3hD}w3N8uQ z34aMF2+#<02o49Q2S5hd26F}t1*HW*1l$CG1SA8<18oC60|k+R_qWRO12zo|0004j zG6?`x2^EDSm%-5k6_=pV0|}RHxd8~b{PF`&0ki}G5C#AM04W0lmj@68NeU0b53vL` z0|O2=v4N=qx1C4?MF9j9h0cAqOcVs_2?P#>^=P*`9t3v*m*PnTB9}W&1TCf@1RzK` BkIMi6