diff --git a/100_core/src/gplx/Io_url_.java b/100_core/src/gplx/Io_url_.java index c9671d1f7..cf55cc377 100644 --- a/100_core/src/gplx/Io_url_.java +++ b/100_core/src/gplx/Io_url_.java @@ -18,9 +18,9 @@ along with this program. If not, see . package gplx; import gplx.core.ios.*; /*IoUrlInfo_*/ import gplx.core.stores.*; import gplx.core.envs.*; public class Io_url_ { - public static final Io_url Empty = new Io_url("", IoUrlInfo_.Nil); - public static final Io_url NullPtr = null; - public static final Io_url Parser = new Io_url("", IoUrlInfo_.Nil); + public static final Io_url Empty = new Io_url("", IoUrlInfo_.Nil); + public static final Io_url NullPtr = null; + public static final Io_url Parser = new Io_url("", IoUrlInfo_.Nil); public static Io_url as_(Object obj) {return obj instanceof Io_url ? (Io_url)obj : null;} public static Io_url cast(Object obj) {try {return (Io_url)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, Io_url.class, obj);}} public static Io_url Usr() { @@ -93,4 +93,11 @@ public class Io_url_ { ) ); } + public static Io_url[] Ary(String... ary) { + int len = ary.length; + Io_url[] rv = new Io_url[len]; + for (int i = 0; i < len; ++i) + rv[i] = Io_url_.new_any_(ary[i]); + return rv; + } } diff --git a/150_gfui/src/gplx/gfui/kits/swts/Swt_html.java b/150_gfui/src/gplx/gfui/kits/swts/Swt_html.java index afc66057a..8c516af81 100644 --- a/150_gfui/src/gplx/gfui/kits/swts/Swt_html.java +++ b/150_gfui/src/gplx/gfui/kits/swts/Swt_html.java @@ -91,7 +91,7 @@ public class Swt_html implements Gxw_html, Swt_control, FocusListener, Gfo_evt_m public void Html_js_cbks_add(String func_name, Gfo_invk invk) {new Swt_html_func(browser, func_name, invk);} public String Html_js_eval_script(String script) {return Eval_script_as_str(script);} public Object Html_js_eval_script_as_obj(String script) {return Eval_script(script);} - public boolean Html_js_eval_proc_as_bool(String proc, Object... args) {return Bool_.cast(Html_js_eval_proc_as_obj(proc, args));} + public boolean Html_js_eval_proc_as_bool(String proc, Object... args) {return Bool_.cast(Html_js_eval_proc_as_obj(proc, args));} public String Html_js_eval_proc_as_str(String proc, Object... args) {return Object_.Xto_str_strict_or_null(Html_js_eval_proc_as_obj(proc, args));} public String Html_js_send_json(String name, String data) { String script = String_.Format("return {0}('{1}');", name, String_.Replace(data, "\n", "") ); diff --git a/400_xowa/src/gplx/core/caches/GfoCacheMgr_tst.java b/400_xowa/src/gplx/core/caches/GfoCacheMgr_tst.java deleted file mode 100644 index 10a4e70a1..000000000 --- a/400_xowa/src/gplx/core/caches/GfoCacheMgr_tst.java +++ /dev/null @@ -1,66 +0,0 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012 gnosygnu@gmail.com - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ -package gplx.core.caches; import gplx.*; import gplx.core.*; -import org.junit.*; import gplx.core.envs.*; -public class GfoCacheMgr_tst { - @Before public void init() {fxt = new GfoCacheMgr_fxt();} GfoCacheMgr_fxt fxt; - @Test public void teardown() {Env_.TickCount_Test = -1;} - @Test public void Basic() {fxt.run_Add("a").Expd_curSize_(1).Expd_itms_("a").tst();} -// @Test public void Reduce() {fxt.run_Add("a", "b", "c", "d", "e").Expd_curSize_(3).Expd_itms_("c", "d", "e").tst();} -// @Test public void Access() {fxt.run_Add("a", "b", "c", "d").run_Get("b", "a").run_Add("e").Expd_curSize_(3).Expd_itms_("b", "a", "e").tst();} -// @Test public void Sizes() {fxt.run_Add("abc", "d", "e").Expd_curSize_(2).Expd_itms_("d", "e").tst();} -} -class GfoCacheMgr_fxt { - Gfo_cache_mgr mgr = new Gfo_cache_mgr().Max_size_(4).Reduce_by_(2); - public GfoCacheMgr_fxt() { - Env_.TickCount_Test = 1; - } - public GfoCacheMgr_fxt run_Add(String... ary) { - for (int i = 0; i < ary.length; i++) { - String s = ary[i]; - mgr.Add(Bry_.new_u8(s), new GfoCacheItm_mock(s), String_.Len(s)); - Env_.TickCount_Test++; - } - return this; - } - public GfoCacheMgr_fxt run_Get(String... ary) { - for (int i = 0; i < ary.length; i++) { - String s = ary[i]; - mgr.Get_by_key(Bry_.new_u8(s)); - Env_.TickCount_Test++; - } - return this; - } - public GfoCacheMgr_fxt Expd_curSize_(int v) {expd_curSize = v; return this;} private int expd_curSize = -1; - public GfoCacheMgr_fxt Expd_itms_(String... v) {expd_itms = v; return this;} private String[] expd_itms; - public GfoCacheMgr_fxt tst() { - if (expd_curSize != -1) Tfds.Eq(expd_curSize, mgr.Cur_size(), "curSize"); - if (expd_itms != null) { - String[] actl = new String[mgr.Count()]; - for (int i = 0; i < actl.length; i++) - actl[i] = ((GfoCacheItm_mock)mgr.Get_at(i)).S(); - Tfds.Eq_ary_str(expd_itms, actl, "itms"); - } - return this; - } -} -class GfoCacheItm_mock implements Rls_able { - public void Rls() {} - public String S() {return s;} private String s; - public GfoCacheItm_mock(String s) {this.s = s;} -} diff --git a/400_xowa/src/gplx/core/caches/Gfo_cache_data.java b/400_xowa/src/gplx/core/caches/Gfo_cache_data.java new file mode 100644 index 000000000..5e1ed796d --- /dev/null +++ b/400_xowa/src/gplx/core/caches/Gfo_cache_data.java @@ -0,0 +1,46 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.core.caches; import gplx.*; import gplx.core.*; +import gplx.core.envs.*; +class Gfo_cache_data implements gplx.CompareAble, Rls_able { + private int count = 0; + public Gfo_cache_data(byte[] key, Rls_able val, int size) { + this.key = key; this.val = val; + this.size = size; + this.count = 1; + } + public byte[] Key() {return key;} private final byte[] key; + public Rls_able Val() {return val;} private Rls_able val; + public int Size() {return size;} private int size; + + public Object Val_and_update() { + ++count; + return val; + } + public void Val_(Rls_able val, int size) { + this.val = val; + this.size = size; + } + public int compareTo(Object obj) { + Gfo_cache_data comp = (Gfo_cache_data)obj; + return -Long_.Compare(count, comp.count); // "-" to sort most-recent first + } + public void Rls() { + val.Rls(); + } +} diff --git a/400_xowa/src/gplx/core/caches/Gfo_cache_mgr.java b/400_xowa/src/gplx/core/caches/Gfo_cache_mgr.java index 1c37b49f8..b228ed337 100644 --- a/400_xowa/src/gplx/core/caches/Gfo_cache_mgr.java +++ b/400_xowa/src/gplx/core/caches/Gfo_cache_mgr.java @@ -16,27 +16,71 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.core.caches; import gplx.*; import gplx.core.*; -import gplx.core.consoles.*; import gplx.core.envs.*; public class Gfo_cache_mgr { - private Ordered_hash hash = Ordered_hash_.New_bry(); - private Ordered_hash recent = Ordered_hash_.New_bry(); - public int Max_size() {return max_size;} public Gfo_cache_mgr Max_size_(int v) {max_size = v; return this;} private int max_size; - public int Reduce_by() {return reduce_by;} public Gfo_cache_mgr Reduce_by_(int v) {reduce_by = v; return this;} private int reduce_by; - public int Cur_size() {return cur_size;} private int cur_size; - public int Count() {return hash.Count();} - public void Clear() {hash.Clear(); recent.Clear(); cur_size = 0;} - @gplx.Internal protected Object Get_at(int i) { + private final Ordered_hash hash = Ordered_hash_.New_bry(); + private final List_adp tmp_delete = List_adp_.New(); + public int Cur_size() {return cur_size;} private int cur_size; + public int Max_size() {return max_size;} public Gfo_cache_mgr Max_size_(int v) {max_size = v; return this;} private int max_size; + public int Reduce_by() {return reduce_by;} public Gfo_cache_mgr Reduce_by_(int v) {reduce_by = v; return this;} private int reduce_by; + public void Clear() { + synchronized (tmp_delete) { + hash.Clear(); + cur_size = 0; + } + } + public Object Get_by_key(byte[] key) { + Object o = hash.Get_by(key); + return o == null ? null : ((Gfo_cache_data)o).Val_and_update(); + } + public void Add_replace(byte[] key, Rls_able val, int size) { + Object o = hash.Get_by(key); + if (o == null) + Add(key, val, size); + else { + Gfo_cache_data itm = (Gfo_cache_data)o; + synchronized (itm) { + cur_size -= itm.Size(); + cur_size += size; + itm.Val_(val, size); + } + } + } + public void Add(byte[] key, Rls_able val, int size) { + synchronized (tmp_delete) { + if (hash.Has(key)) return; // THREAD: since Get is not locked, it's possible to Add the same item twice + cur_size += size; + Gfo_cache_data itm = new Gfo_cache_data(key, val, size); + hash.Add(key, itm); + if (cur_size > max_size) this.Reduce(); + } + } + private void Reduce() { + hash.Sort(); + int len = hash.Len(); + int list_size = 0; + for (int i = 0; i < len; ++i) { + Gfo_cache_data itm = (Gfo_cache_data)hash.Get_at(i); + int new_size = list_size + itm.Size(); + if (new_size > reduce_by) + tmp_delete.Add(itm); + else + list_size = new_size; + } + this.cur_size = list_size; + len = tmp_delete.Len(); + for (int i = 0; i < len; ++i) { + Gfo_cache_data itm = (Gfo_cache_data)tmp_delete.Get_at(i); + hash.Del(itm.Key()); + } + tmp_delete.Clear(); + } + public int Test__len() {return hash.Len();} + public Object Test__get_at(int i) { Gfo_cache_data rv = (Gfo_cache_data)hash.Get_at(i); return rv.Val(); } - public Object Get_by_key(byte[] key) { - Object o = hash.Get_by(key); if (o == null) return null; - Gfo_cache_data rv = (Gfo_cache_data)o; - rv.Timestamp_update(); - Object recent_itm = recent.Get_by(key); - if (recent_itm == null) recent.Add(key, rv); - return rv.Val(); - } + // NOTE: not called yet + /* public void Del(byte[] key) { Object o = hash.Get_by(key); if (o == null) return; Gfo_cache_data itm = (Gfo_cache_data)o; @@ -44,80 +88,5 @@ public class Gfo_cache_mgr { hash.Del(itm.Key()); itm.Rls(); } - public void Add_replace(byte[] key, Rls_able val, int size) { -// Del(key); -// Add(key, val, size); - Object o = hash.Get_by(key); - if (o == null) - Add(key, val, size); - else { - Gfo_cache_data itm = (Gfo_cache_data)o; - cur_size -= itm.Size(); - cur_size += size; - itm.Replace(val, size); - } - } - public void Add(byte[] key, Rls_able val, int size) { -// if (cur_size + size > 600000000) ReduceCache(); - cur_size += size; -// ++cur_size; - Gfo_cache_data itm = new Gfo_cache_data(key, val, size); - hash.Add(key, itm); - } - public void Reduce_recent() { -// Console_adp__sys.Instance.WriteLine("reducing"); - int len = recent.Count(); - for (int i = 0; i < len; i++) { - Gfo_cache_data itm = (Gfo_cache_data)recent.Get_at(i); - itm.Rls(); // releases root - } - recent.Clear(); - } - public void Reduce_cache() { - Console_adp__sys.Instance.Write_str_w_nl("compacting:"); -// hash.Sort(); -// int len = hash.Count(); -// List_adp deleted = List_adp_.New(); -// int deleted_size = 0, deleted_count = 0; -// for (int i = 0; i < len; i++) { -// Gfo_cache_data itm = (Gfo_cache_data)hash.Get_at(i); -// int new_deleted_size = deleted_size + 1;//itm.Size(); -// if (new_deleted_size > 4000 && deleted_count > 0) break; -// deleted.Add(itm); -// deleted_count++; -// deleted_size = new_deleted_size; -// } -// len = deleted.Count(); -// for (int i = 0; i < len; i++) { -// Gfo_cache_data itm = (Gfo_cache_data)deleted.Get_at(i); -// cur_size --; -// hash.Del(bry_ref.Val_(itm.Key())); -// itm.Rls(); -// } -// deleted.Clear(); - - int len = hash.Count(); - for (int i = 0; i < len; i++) { - Gfo_cache_data itm = (Gfo_cache_data)hash.Get_at(i); -// hash.Del(bry_ref.Val_(itm.Key())); - itm.Rls(); - } - } -} -class Gfo_cache_data implements gplx.CompareAble, Rls_able { - public Gfo_cache_data(byte[] key, Rls_able val, int size) {this.key = key; this.val = val; this.size = size; this.timestamp = Env_.TickCount();} - public byte[] Key() {return key;} private byte[] key; - public Rls_able Val() {return val;} private Rls_able val; - public int Size() {return size;} private int size; - public void Replace(Rls_able val, int size) {this.val = val; this.size = size;} - public long Timestamp() {return timestamp;} public void Timestamp_update() {timestamp = Env_.TickCount();} private long timestamp; - public int compareTo(Object obj) { - Gfo_cache_data comp = (Gfo_cache_data)obj; - return Long_.Compare(timestamp, comp.timestamp); - } - public void Rls() { - val.Rls(); -// val = null; -// key = null; - } + */ } diff --git a/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_base.java b/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_base.java index 244313755..388120646 100644 --- a/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_base.java +++ b/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_base.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ package gplx.core.caches; import gplx.*; import gplx.core.*; public class Gfo_cache_mgr_base { - private Ordered_hash hash = Ordered_hash_.New_bry(); + private final Ordered_hash hash = Ordered_hash_.New_bry(); public int Compress_max() {return compress_max;} public void Compress_max_(int v) {compress_max = v;} private int compress_max = 16; public int Compress_to() {return compress_to;} public void Compress_to_(int v) {compress_to = v;} private int compress_to = 8; protected Object Base_get_or_null(byte[] key) { diff --git a/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_bry.java b/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_bry.java index 32cf29720..128643e33 100644 --- a/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_bry.java +++ b/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_bry.java @@ -35,7 +35,7 @@ class Gfo_cache_itm_comparer implements gplx.core.lists.ComparerAble { Gfo_cache_itm rhs = (Gfo_cache_itm)rhsObj; return Long_.Compare(lhs.Touched(), rhs.Touched()); } - public static final Gfo_cache_itm_comparer Touched_asc = new Gfo_cache_itm_comparer(); + public static final Gfo_cache_itm_comparer Touched_asc = new Gfo_cache_itm_comparer(); } class Io_url_exists_mgr { private gplx.core.caches.Gfo_cache_mgr_bry cache_mgr = new gplx.core.caches.Gfo_cache_mgr_bry(); diff --git a/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_tst.java b/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_tst.java new file mode 100644 index 000000000..52db0405e --- /dev/null +++ b/400_xowa/src/gplx/core/caches/Gfo_cache_mgr_tst.java @@ -0,0 +1,73 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.core.caches; import gplx.*; import gplx.core.*; +import org.junit.*; import gplx.core.tests.*; import gplx.core.envs.*; +public class Gfo_cache_mgr_tst { + @Before public void init() {fxt.Clear();} private final Gfo_cache_mgr_fxt fxt = new Gfo_cache_mgr_fxt(); + @Test public void Basic() { + fxt.Exec__add("a"); + fxt.Test__cur_size(1); + fxt.Test__itms("a"); + } + @Test public void Reduce() { + fxt.Exec__add("a", "b", "c", "d", "e"); + fxt.Test__cur_size(2); + fxt.Test__itms("a", "b"); + } + @Test public void Reduce_after_get() { + fxt.Exec__add("a", "b", "c", "d"); + fxt.Exec__get("a", "c"); + fxt.Exec__add("e"); + fxt.Test__itms("a", "c"); + } +} +class Gfo_cache_mgr_fxt { + private final Gfo_cache_mgr mgr = new Gfo_cache_mgr().Max_size_(4).Reduce_by_(2); + public void Clear() {mgr.Clear();} + public Gfo_cache_mgr_fxt Exec__add(String... ary) { + int len = ary.length; + for (int i = 0; i < len; ++i) { + String itm = ary[i]; + byte[] key = Bry_.new_u8(itm); + mgr.Add(key, new Gfo_cache_itm_mock(itm), key.length); + } + return this; + } + public Gfo_cache_mgr_fxt Exec__get(String... ary) { + int len = ary.length; + for (int i = 0; i < len; ++i) { + String itm = ary[i]; + mgr.Get_by_key(Bry_.new_u8(itm)); + } + return this; + } + public Gfo_cache_mgr_fxt Test__cur_size(int expd) {Gftest.Eq__int(expd, mgr.Cur_size(), "cur_size"); return this;} + public Gfo_cache_mgr_fxt Test__itms(String... expd) { + int len = mgr.Test__len(); + String[] actl = new String[len]; + for (int i = 0; i < len; ++i) + actl[i] = ((Gfo_cache_itm_mock)mgr.Test__get_at(i)).Val(); + Gftest.Eq__ary(expd, actl, "itms"); + return this; + } +} +class Gfo_cache_itm_mock implements Rls_able { + public Gfo_cache_itm_mock(String val) {this.val = val;} + public String Val() {return val;} private String val; + public void Rls() {} +} diff --git a/400_xowa/src/gplx/langs/htmls/Gfh_utl.java b/400_xowa/src/gplx/langs/htmls/Gfh_utl.java index 3da0f9654..dbab17475 100644 --- a/400_xowa/src/gplx/langs/htmls/Gfh_utl.java +++ b/400_xowa/src/gplx/langs/htmls/Gfh_utl.java @@ -162,18 +162,19 @@ public class Gfh_utl { public static byte[] Del_comments(Bry_bfr bfr, byte[] src, int pos, int end) { while (true) { if (pos >= end) break; - int comm_bgn = Bry_find_.Find_fwd(src, Gfh_tag_.Comm_bgn, pos); // look for - if (comm_end == Bry_find_.Not_found) { // not found; consume rest - bfr.Add_mid(src, pos, end); - break; + int comm_bgn_rhs = comm_bgn + Gfh_tag_.Comm_bgn_len; + int comm_end = Bry_find_.Find_fwd(src, Gfh_tag_.Comm_end, comm_bgn_rhs); // look for --> + if (comm_end == Bry_find_.Not_found) { // --> not found + bfr.Add_mid(src, pos, comm_bgn); // add everything between pos and comm_bgn; EX: "ac" , "ac");} - @Test public void Bgn_missing() {fxt.Test_del_comments("a b c" , "a b c");} - @Test public void End_missing() {fxt.Test_del_comments("ace" , "ace");} @Test public void Escape() { fxt.Test_escape_html(Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, "a present diff --git a/400_xowa/src/gplx/langs/htmls/Gfh_utl__comments__tst.java b/400_xowa/src/gplx/langs/htmls/Gfh_utl__comments__tst.java new file mode 100644 index 000000000..180768ec6 --- /dev/null +++ b/400_xowa/src/gplx/langs/htmls/Gfh_utl__comments__tst.java @@ -0,0 +1,26 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.langs.htmls; import gplx.*; import gplx.langs.*; +import org.junit.*; +public class Gfh_utl__comments__tst { + @Before public void init() {fxt.Clear();} private final Gfh_class_fxt fxt = new Gfh_class_fxt(); + @Test public void Basic() {fxt.Test_del_comments("ac" , "ac");} + @Test public void Bgn_missing() {fxt.Test_del_comments("a b c" , "a b c");} + @Test public void End_missing() {fxt.Test_del_comments("ace" , "ace");} +} diff --git a/400_xowa/src/gplx/langs/mustaches/Mustache_itm_render_tst.java b/400_xowa/src/gplx/langs/mustaches/Mustache_itm_render_tst.java index b31ff9b00..9a3ed9001 100644 --- a/400_xowa/src/gplx/langs/mustaches/Mustache_itm_render_tst.java +++ b/400_xowa/src/gplx/langs/mustaches/Mustache_itm_render_tst.java @@ -111,6 +111,18 @@ public class Mustache_itm_render_tst { , "abc11dc12def2g" ); } + @Test public void Section_owner() { + fxt.Init__root + ( fxt.Make_mock(0).Add_subs("subs1" + , fxt.Make_mock(1).Add_prop("prop1", "a").Add_subs("subs2" + , fxt.Make_mock(11).Add_prop("prop2", "1") + ) + )); + fxt.Test__parse + ( "{{#subs1}}{{#subs2}}{{prop1}}{{prop2}}{{/subs2}}{{/subs1}}" // prop1 is cited in subs2, but value belongs to subs1 + , "a1" + ); + } } class Mustache_itm_render_fxt { private final Mustache_tkn_parser parser = new Mustache_tkn_parser(); diff --git a/400_xowa/src/gplx/langs/mustaches/Mustache_render_ctx.java b/400_xowa/src/gplx/langs/mustaches/Mustache_render_ctx.java index 6cfae3c5b..210c30c3a 100644 --- a/400_xowa/src/gplx/langs/mustaches/Mustache_render_ctx.java +++ b/400_xowa/src/gplx/langs/mustaches/Mustache_render_ctx.java @@ -28,11 +28,21 @@ public class Mustache_render_ctx { } public boolean Render_variable(Mustache_bfr bfr, String key) { boolean rv = false; + int stack_pos = stack.Len(); Mustache_doc_itm itm = cur; while (itm != Mustache_doc_itm_.Null_itm) { - boolean resolved = cur.Mustache__write(key, bfr); - if (resolved) {rv = true; break;} - else break; // TODO_OLD: itm = itm.Get_owner(); + boolean resolved = itm.Mustache__write(key, bfr); + if (resolved) { + rv = true; + break; + } + else { + --stack_pos; + if (stack_pos == -1) // nothing else in stack + break; + else + itm = ((Mustache_stack_itm)stack.Get_at(stack_pos)).cur; + } } return rv; } diff --git a/400_xowa/src/gplx/xowa/Xoa_app.java b/400_xowa/src/gplx/xowa/Xoa_app.java index d189960b9..43d86faa6 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app.java +++ b/400_xowa/src/gplx/xowa/Xoa_app.java @@ -55,7 +55,6 @@ public interface Xoa_app extends Gfo_invk { Xow_xwiki_itm_parser Xwiki_mgr__itm_parser(); boolean Bldr__running(); void Bldr__running_(boolean v); Gfo_usr_dlg Usr_dlg(); - Bry_bfr_mkr Utl__bfr_mkr(); Json_parser Utl__json_parser(); Gfo_inet_conn Utl__inet_conn(); Xoa_meta_mgr Dbmeta_mgr(); diff --git a/400_xowa/src/gplx/xowa/Xoa_app_.java b/400_xowa/src/gplx/xowa/Xoa_app_.java index 80879117a..96b44da85 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app_.java +++ b/400_xowa/src/gplx/xowa/Xoa_app_.java @@ -34,7 +34,7 @@ public class Xoa_app_ { } } public static final String Name = "xowa"; - public static final String Version = "3.7.3.1"; + public static final String Version = "3.7.4.1"; public static String Build_date = "2012-12-30 00:00:00"; public static String Op_sys_str; public static String User_agent = ""; diff --git a/400_xowa/src/gplx/xowa/Xoa_page.java b/400_xowa/src/gplx/xowa/Xoa_page.java index ac467b2e7..c5eb966ab 100644 --- a/400_xowa/src/gplx/xowa/Xoa_page.java +++ b/400_xowa/src/gplx/xowa/Xoa_page.java @@ -22,7 +22,7 @@ public interface Xoa_page { Xoa_url Url(); byte[] Url_bry_safe(); Xoa_ttl Ttl(); Xopg_db_data Db(); - Xopg_redirect_data Redirect(); + Xopg_redirect_mgr Redirect(); Xopg_html_data Html_data(); Xopg_hdump_data Hdump_mgr(); diff --git a/400_xowa/src/gplx/xowa/Xoae_app.java b/400_xowa/src/gplx/xowa/Xoae_app.java index 8a4b196a5..a15821a43 100644 --- a/400_xowa/src/gplx/xowa/Xoae_app.java +++ b/400_xowa/src/gplx/xowa/Xoae_app.java @@ -186,13 +186,13 @@ public class Xoae_app implements Xoa_app, Gfo_invk { user.App_term(); usr_dlg.Log_many("", "", "term:app_term"); log_wtr.Log_term(); usr_dlg.Log_many("", "", "term:log_wtr"); log_mgr.Rls(); usr_dlg.Log_many("", "", "term:log_mgr"); - gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(); + gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(this); wiki_mgr.Rls(); usr_dlg.Log_many("", "", "term:wiki_mgr"); return true; } public void Reset_all() { this.Free_mem(true); - gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(); + gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(this); Env_.GarbageCollect(); } public void Free_mem(boolean clear_ctx) { diff --git a/400_xowa/src/gplx/xowa/Xoae_page.java b/400_xowa/src/gplx/xowa/Xoae_page.java index 889938bba..d17d220e3 100644 --- a/400_xowa/src/gplx/xowa/Xoae_page.java +++ b/400_xowa/src/gplx/xowa/Xoae_page.java @@ -35,7 +35,7 @@ public class Xoae_page implements Xoa_page { public Xoa_url Url() {return url;} public Xoae_page Url_(Xoa_url v) {url = v; return this;} private Xoa_url url = Xoa_url.blank(); public byte[] Url_bry_safe() {return url == null ? Bry_.Empty : url.Raw();} public Xopg_db_data Db() {return db;} private final Xopg_db_data db = new Xopg_db_data(); - public Xopg_redirect_data Redirect() {return redirect;} private final Xopg_redirect_data redirect = new Xopg_redirect_data(); + public Xopg_redirect_mgr Redirect() {return redirect;} private final Xopg_redirect_mgr redirect = new Xopg_redirect_mgr(); public Xopg_html_data Html_data() {return html;} private final Xopg_html_data html = new Xopg_html_data(); public Xopg_hdump_data Hdump_mgr() {return hdump;} private final Xopg_hdump_data hdump = new Xopg_hdump_data(); @@ -92,7 +92,7 @@ public class Xoae_page implements Xoa_page { ref_mgr.Grps_clear(); html_cmd_mgr.Clear(); wdata_external_lang_links.Reset(); - if (clear_scrib) wiki.Parser_mgr().Scrib().Core_page_changed(this); + if (clear_scrib) wiki.Parser_mgr().Scrib().When_page_changed(this); slink_list.Clear(); tab_data.Clear(); pages_recursed = false; diff --git a/400_xowa/src/gplx/xowa/Xop_fxt.java b/400_xowa/src/gplx/xowa/Xop_fxt.java index 78a2f7129..8b438e562 100644 --- a/400_xowa/src/gplx/xowa/Xop_fxt.java +++ b/400_xowa/src/gplx/xowa/Xop_fxt.java @@ -393,7 +393,7 @@ public class Xop_fxt { } } public void Test_html_modules_js(String expd) { - Bry_bfr bfr = app.Utl__bfr_mkr().Get_k004(); + Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_k004(); this.Page().Html_data().Head_mgr().Init(app, wiki, this.Page()); this.Page().Html_data().Head_mgr().Bfr_arg__add(bfr); bfr.Mkr_rls(); diff --git a/400_xowa/src/gplx/xowa/Xowe_wiki.java b/400_xowa/src/gplx/xowa/Xowe_wiki.java index 15510bf1c..2461c4a61 100644 --- a/400_xowa/src/gplx/xowa/Xowe_wiki.java +++ b/400_xowa/src/gplx/xowa/Xowe_wiki.java @@ -135,7 +135,7 @@ public class Xowe_wiki implements Xow_wiki, Gfo_invk, Gfo_evt_itm { public void Wdata_wiki_lang_(byte[] v) {this.wdata_wiki_lang = v; Wdata_wiki_abrv_();} // TEST: public byte[] Wdata_wiki_abrv() {return wdata_wiki_abrv;} private byte[] wdata_wiki_abrv; private int wdata_wiki_tid; private void Wdata_wiki_abrv_() { - Bry_bfr bfr = app.Utl__bfr_mkr().Get_b128(); + Bry_bfr bfr = utl__bry_bfr_mkr.Get_b128(); Xow_abrv_wm_.To_abrv(bfr, wdata_wiki_lang, Int_obj_ref.New(wdata_wiki_tid)); wdata_wiki_abrv = bfr.To_bry_and_rls(); } @@ -216,6 +216,7 @@ public class Xowe_wiki implements Xow_wiki, Gfo_invk, Gfo_evt_itm { init_in_process = false; app.Api_root().Wikis().Get(domain_bry).Subscribe(this); app.Site_cfg_mgr().Load(this); + app.Addon_mgr().Load_by_wiki(this); } public void Rls() { if (rls_list != null) { diff --git a/400_xowa/src/gplx/xowa/Xowe_wiki_.java b/400_xowa/src/gplx/xowa/Xowe_wiki_.java index 742fafc54..bc2ee3440 100644 --- a/400_xowa/src/gplx/xowa/Xowe_wiki_.java +++ b/400_xowa/src/gplx/xowa/Xowe_wiki_.java @@ -28,9 +28,9 @@ public class Xowe_wiki_ { public static void Rls_mem_if_needed(Xowe_wiki wiki) { Xoae_app app = wiki.Appe(); if (gplx.core.envs.Env_.System_memory_free() < app.Sys_cfg().Free_mem_when()) // check if low in memory - Xowe_wiki_.Rls_mem(wiki, false); // clear caches (which will clear bry_bfr_mkr) - else // not low in memory - app.Utl__bfr_mkr().Clear(); // clear bry_bfr_mkr only; NOTE: call before page parse, not when page is first added, else threading errors; DATE:2014-05-30 + Xowe_wiki_.Rls_mem(wiki, false); // clear caches (which will clear bry_bfr_mkr) + else // not low in memory + wiki.Utl__bfr_mkr().Clear(); // clear bry_bfr_mkr only; NOTE: call before page parse, not when page is first added, else threading errors; DATE:2014-05-30 } public static void Rls_mem(Xowe_wiki wiki, boolean clear_ctx) { wiki.Appe().Free_mem(clear_ctx); diff --git a/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_data_itm.java b/400_xowa/src/gplx/xowa/addons/Xoax_addon_itm__init.java similarity index 57% rename from 400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_data_itm.java rename to 400_xowa/src/gplx/xowa/addons/Xoax_addon_itm__init.java index 1b0d5a296..157d95a9c 100644 --- a/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_data_itm.java +++ b/400_xowa/src/gplx/xowa/addons/Xoax_addon_itm__init.java @@ -15,11 +15,9 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package gplx.xowa.apps.cfgs.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.cfgs.*; -public class Xocfg_data_itm { - public Xocfg_data_itm(String key, String usr, String ctx, String val) {this.key = key; this.usr = usr; this.ctx = ctx; this.val = val;} - public String Key() {return key;} private final String key; - public String Usr() {return usr;} private final String usr; - public String Ctx() {return ctx;} private String ctx; - public String Val() {return val;} private String val; +package gplx.xowa.addons; import gplx.*; import gplx.xowa.*; +import gplx.xowa.bldrs.wkrs.*; +public interface Xoax_addon_itm__init { + void Init_addon_by_app(Xoa_app app); + void Init_addon_by_wiki(Xow_wiki wiki); } 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 43ef25cad..f65675a74 100644 --- a/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java @@ -17,8 +17,7 @@ along with this program. If not, see . */ package gplx.xowa.addons; import gplx.*; import gplx.xowa.*; public class Xoax_addon_mgr { - private final Ordered_hash hash = Ordered_hash_.New(); - // THREAD: must synchronized else two search tabs will fail on startup + private final Ordered_hash hash = Ordered_hash_.New(); // LOCK: must synchronized else two search tabs will fail on startup public Xoax_addon_itm Itms__get_or_null(String key) {synchronized (hash) {return (Xoax_addon_itm)hash.Get_by(key);}} public void Itms__add_many(Xoax_addon_itm... ary) { for (Xoax_addon_itm itm : ary) @@ -49,6 +48,7 @@ public class Xoax_addon_mgr { // specials , new gplx.xowa.addons.wikis.registrys .Wiki_registry_addon() , new gplx.xowa.addons.wikis.imports .Xow_import_addon() + , new gplx.xowa.addons.bldrs.xodirs .Xobc_xodir_addon() , new gplx.xowa.addons.bldrs.centrals .Xobc_task_addon() , new gplx.xowa.addons.apps.helps.logs .Xolog_addon() @@ -63,6 +63,14 @@ public class Xoax_addon_mgr { int len = hash.Len(); for (int i = 0; i < len; ++i) { Xoax_addon_itm addon = (Xoax_addon_itm)hash.Get_at(i); + + // init + if (Type_adp_.Implements_intf_obj(addon, Xoax_addon_itm__init.class)) { + Xoax_addon_itm__init addon_init = (Xoax_addon_itm__init)addon; + addon_init.Init_addon_by_app(app); + init_list.Add(addon_init); + } + // add bldr cmds if (Type_adp_.Implements_intf_obj(addon, Xoax_addon_itm__bldr.class)) { Xoax_addon_itm__bldr addon_bldr = (Xoax_addon_itm__bldr)addon; @@ -86,4 +94,12 @@ public class Xoax_addon_mgr { } } } + public void Load_by_wiki(Xow_wiki wiki) { + int len = init_list.Len(); + for (int i = 0; i < len; ++i) { + Xoax_addon_itm__init itm = (Xoax_addon_itm__init)init_list.Get_at(i); + itm.Init_addon_by_wiki(wiki); + } + } + private final List_adp init_list = List_adp_.New(); } diff --git a/400_xowa/src/gplx/xowa/addons/apps/helps/logs/Xolog_special.java b/400_xowa/src/gplx/xowa/addons/apps/helps/logs/Xolog_special.java index b8abcdbdf..9560a5564 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/helps/logs/Xolog_special.java +++ b/400_xowa/src/gplx/xowa/addons/apps/helps/logs/Xolog_special.java @@ -42,11 +42,11 @@ public class Xolog_special implements Xow_special_page { } if (redirect) { - String redirect_ttl_str = special__meta.Ttl_str() + "?cmd=view"; + Xoa_url_args_bldr args_bldr = new Xoa_url_args_bldr(); + args_bldr.Add("cmd", "view"); if (redirect_to_same_file && file != null) - redirect_ttl_str += "&file=" + file; - Xoa_ttl redirect_ttl = wiki.Ttl_parse(Bry_.new_u8(redirect_ttl_str)); - page.Redirect().Itms__add__special(Xoa_url.New(wiki, redirect_ttl), redirect_ttl); + args_bldr.Add("file", file); + page.Redirect().Itms__add__special(wiki, Prototype.Special__meta(), args_bldr.To_ary()); return; } else @@ -66,6 +66,14 @@ public class Xolog_special implements Xow_special_page { public Xow_special_page Special__clone() {return this;} public static final Xow_special_page Prototype = new Xolog_special(Xow_special_meta.New_xo("XowaLog", "Logs")); } +class Xoa_url_args_bldr { + private final List_adp list = List_adp_.New(); + public Xoa_url_args_bldr Add(String key, Object val) { + list.Add(Keyval_.new_(key, val)); + return this; + } + public Keyval[] To_ary() {return (Keyval[])list.To_ary_and_clear(Keyval.class);} +} class Xolog_file_utl {// yyyyMMdd_HHmmss.log private static final String Gui__date_fmt = "yyyy-MM-dd HH:mm:ss"; public static String To_name(Io_url url) {return To_name(url.NameOnly());} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/centrals/Xobc_task_addon.java b/400_xowa/src/gplx/xowa/addons/bldrs/centrals/Xobc_task_addon.java index 9469846ce..b75a89704 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/centrals/Xobc_task_addon.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/centrals/Xobc_task_addon.java @@ -17,8 +17,14 @@ along with this program. If not, see . */ package gplx.xowa.addons.bldrs.centrals; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.specials.*; import gplx.xowa.htmls.bridges.*; -import gplx.xowa.addons.bldrs.infos.*; -public class Xobc_task_addon implements Xoax_addon_itm, Xoax_addon_itm__special, Xoax_addon_itm__json { +import gplx.xowa.addons.bldrs.infos.*; import gplx.xowa.addons.bldrs.xodirs.*; +public class Xobc_task_addon implements Xoax_addon_itm, Xoax_addon_itm__special, Xoax_addon_itm__json, Xoax_addon_itm__init { + public Xobc_xodir_mgr Xodir_mgr() {return xodir_mgr;} private Xobc_xodir_mgr xodir_mgr; + public void Xodir_mgr_(Xobc_xodir_mgr v) {this.xodir_mgr = v;} + public void Init_addon_by_app(Xoa_app app) { + this.xodir_mgr = new Xobc_xodir_mgr__pc(app); + } + public void Init_addon_by_wiki(Xow_wiki wiki) {} public Xow_special_page[] Special_pages() { return new Xow_special_page[] { Xobc_task_special.Prototype @@ -31,5 +37,5 @@ public class Xobc_task_addon implements Xoax_addon_itm, Xoax_addon_itm__special, }; } - public String Addon__key() {return "xowa.imports.downloads";} + public String Addon__key() {return ADDON__KEY;} public static final String ADDON__KEY = "xowa.imports.downloads"; } diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/centrals/cmds/Xobc_cmd__unzip.java b/400_xowa/src/gplx/xowa/addons/bldrs/centrals/cmds/Xobc_cmd__unzip.java index f2bed0896..726bcdb2e 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/centrals/cmds/Xobc_cmd__unzip.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/centrals/cmds/Xobc_cmd__unzip.java @@ -29,6 +29,7 @@ public class Xobc_cmd__unzip extends Xobc_cmd__base { @Override public String Cmd_type() {return CMD_TYPE;} public static final String CMD_TYPE = "xowa.core.ios.zips.zip_unzip"; @Override public String Cmd_name() {return "unzip";} @Override public boolean Cmd_suspendable() {return true;} + @Override public String Cmd_fallback() {return Xobc_cmd__verify_fil.CMD_TYPE;} // if unzip fails, backtrack to verify; if verify fails, it'll backtrack to download; DATE:2016-07-25 @Override protected void Cmd_exec_hook(Xobc_cmd_ctx ctx) { if (wkr.Exec(this, src_fil, trg_dir, trg_fils) == Gfo_prog_ui_.Status__fail) diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_bldr_cfg.java b/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_bldr_cfg.java new file mode 100644 index 000000000..636d31a6c --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_bldr_cfg.java @@ -0,0 +1,37 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.exports.packs.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.exports.*; import gplx.xowa.addons.bldrs.exports.packs.*; +import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; +public class Pack_file_bldr_cfg implements Gfo_invk { + public Io_url Deploy_dir() {return deploy_dir;} private Io_url deploy_dir; + public boolean Pack_html() {return pack_html;} private boolean pack_html = true; + public boolean Pack_file() {return pack_file;} private boolean pack_file = true; + public DateAdp Pack_file_cutoff() {return pack_file_cutoff;} private DateAdp pack_file_cutoff = null; + + public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { + if (ctx.Match(k, Invk__deploy_dir_)) deploy_dir = m.ReadIoUrl("v"); + else if (ctx.Match(k, Invk__pack_html_)) pack_html = m.ReadYn("v"); + else if (ctx.Match(k, Invk__pack_file_)) pack_file = m.ReadYn("v"); + else if (ctx.Match(k, Invk__pack_file_cutoff_)) pack_file_cutoff = m.ReadDate("v"); + else return Gfo_invk_.Rv_unhandled; + return this; + } + private static final String Invk__deploy_dir_ = "deploy_dir_" + , Invk__pack_html_ = "pack_html_", Invk__pack_file_ = "pack_file_", Invk__pack_file_cutoff_ = "pack_file_cutoff_" + ; +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_bldr_cmd.java b/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_bldr_cmd.java index 982330839..06874dfbb 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_bldr_cmd.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_bldr_cmd.java @@ -18,18 +18,17 @@ along with this program. If not, see . package gplx.xowa.addons.bldrs.exports.packs.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.exports.*; import gplx.xowa.addons.bldrs.exports.packs.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; public class Pack_file_bldr_cmd extends Xob_cmd__base { - private Io_url deploy_dir; + private final Pack_file_bldr_cfg cfg = new Pack_file_bldr_cfg(); public Pack_file_bldr_cmd(Xob_bldr bldr, Xowe_wiki wiki) {super(bldr, wiki);} @Override public void Cmd_run() { - new Pack_file_mgr().Exec(wiki, deploy_dir); + new Pack_file_mgr().Exec(wiki, cfg); } @Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { - if (ctx.Match(k, Invk__deploy_dir_)) deploy_dir = m.ReadIoUrl("v"); + if (ctx.Match(k, Invk__cfg)) return cfg; else return super.Invk (ctx, ikey, k, m); - return this; } - private static final String Invk__deploy_dir_ = "deploy_dir_"; + private static final String Invk__cfg = "cfg"; public static final String BLDR_CMD_KEY = "bldr.export.pack.file"; @Override public String Cmd_key() {return BLDR_CMD_KEY;} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_mgr.java b/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_mgr.java index 821b5d210..63427ad85 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/exports/packs/files/Pack_file_mgr.java @@ -20,14 +20,14 @@ import gplx.core.progs.*; import gplx.core.ios.zips.*; import gplx.core.ios.stre import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.fsdb.*; import gplx.fsdb.meta.*; import gplx.xowa.addons.bldrs.centrals.dbs.*; import gplx.xowa.addons.bldrs.centrals.dbs.datas.*; import gplx.xowa.addons.bldrs.centrals.dbs.datas.imports.*; import gplx.xowa.addons.bldrs.centrals.steps.*; import gplx.xowa.addons.bldrs.centrals.hosts.*; class Pack_file_mgr { - public void Exec(Xowe_wiki wiki, Io_url deploy_dir) { + public void Exec(Xowe_wiki wiki, Pack_file_bldr_cfg cfg) { // init wiki.Init_assert(); Io_url wiki_dir = wiki.Fsys_mgr().Root_dir(); Io_url pack_dir = wiki_dir.GenSubDir_nest("tmp", "pack"); Io_mgr.Instance.DeleteDirDeep(pack_dir); Io_mgr.Instance.CreateDirIfAbsent(pack_dir); String wiki_date = wiki.Props().Modified_latest().XtoStr_fmt("yyyy.MM"); - Pack_hash hash = Pack_hash_bldr.Bld(wiki, wiki_dir, pack_dir, wiki_date); + Pack_hash hash = Pack_hash_bldr.Bld(wiki, wiki_dir, pack_dir, wiki_date, cfg.Pack_html(), cfg.Pack_file(), cfg.Pack_file_cutoff()); // get import_tbl byte[] wiki_abrv = wiki.Domain_itm().Abrv_xo(); @@ -50,11 +50,14 @@ class Pack_file_mgr { } // build tasks - Make_task(tmp_bfr, wiki, wiki_date, bc_db, hash, "html", Xobc_import_type.Tid__wiki__core, Xobc_import_type.Tid__wiki__srch, Xobc_import_type.Tid__wiki__html); - Make_task(tmp_bfr, wiki, wiki_date, bc_db, hash, "file", Xobc_import_type.Tid__file__core, Xobc_import_type.Tid__file__data); + if (cfg.Pack_html()) + Make_task(tmp_bfr, wiki, wiki_date, bc_db, hash, "html", Xobc_import_type.Tid__wiki__core, Xobc_import_type.Tid__wiki__srch, Xobc_import_type.Tid__wiki__html); + if (cfg.Pack_file()) + Make_task(tmp_bfr, wiki, wiki_date, bc_db, hash, "file", Xobc_import_type.Tid__file__core, Xobc_import_type.Tid__file__data); bc_conn.Txn_end(); // deploy + Io_url deploy_dir = cfg.Deploy_dir(); if (deploy_dir != null) { Host_eval_itm host_eval = new Host_eval_itm(); int len = hash.Len(); @@ -160,30 +163,41 @@ class Pack_file_mgr { } } class Pack_hash_bldr { - public static Pack_hash Bld(Xow_wiki wiki, Io_url wiki_dir, Io_url pack_dir, String wiki_date) { + public static Pack_hash Bld(Xow_wiki wiki, Io_url wiki_dir, Io_url pack_dir, String wiki_date, boolean pack_html, boolean pack_file, DateAdp pack_file_cutoff) { Pack_hash rv = new Pack_hash(); Pack_zip_name_bldr zip_name_bldr = new Pack_zip_name_bldr(pack_dir, wiki.Domain_str(), String_.new_a7(wiki.Domain_itm().Abrv_wm()), wiki_date); + Xow_db_mgr db_mgr = wiki.Data__core_mgr(); // bld html pack - Xow_db_mgr db_mgr = wiki.Data__core_mgr(); - int len = db_mgr.Dbs__len(); - for (int i = 0; i < len; ++i) { - Xow_db_file file = db_mgr.Dbs__get_at(i); - int pack_tid = Get_pack_tid(file.Tid()); - if (pack_tid == Xobc_import_type.Tid__ignore) continue; - rv.Add(zip_name_bldr, pack_tid, file.Url()); + if (pack_html) { + int len = db_mgr.Dbs__len(); + for (int i = 0; i < len; ++i) { + Xow_db_file file = db_mgr.Dbs__get_at(i); + int pack_tid = Get_pack_tid(file.Tid()); + if (pack_tid == Xobc_import_type.Tid__ignore) continue; + rv.Add(zip_name_bldr, pack_tid, file.Url()); + } + rv.Consolidate(Xobc_import_type.Tid__wiki__srch); } - rv.Consolidate(Xobc_import_type.Tid__wiki__srch); // bld file pack - Fsm_mnt_itm mnt_itm = wiki.File__mnt_mgr().Mnts__get_at(Fsm_mnt_mgr.Mnt_idx_main); - rv.Add(zip_name_bldr, Xobc_import_type.Tid__file__core, wiki_dir.GenSubFil(mnt_itm.Atr_mgr().Db__core().Url_rel())); - if (db_mgr.Props().Layout_file().Tid_is_lot()) { - Fsm_bin_mgr bin_mgr = mnt_itm.Bin_mgr(); - int bin_len = bin_mgr.Dbs__len(); - for (int i = 0; i < bin_len; ++i) { - Fsm_bin_fil bin_fil = bin_mgr.Dbs__get_at(i); - rv.Add(zip_name_bldr, Xobc_import_type.Tid__file__data, bin_fil.Url()); + if (pack_file) { + Fsm_mnt_itm mnt_itm = wiki.File__mnt_mgr().Mnts__get_at(Fsm_mnt_mgr.Mnt_idx_main); + rv.Add(zip_name_bldr, Xobc_import_type.Tid__file__core, wiki_dir.GenSubFil(mnt_itm.Atr_mgr().Db__core().Url_rel())); + if (db_mgr.Props().Layout_file().Tid_is_lot()) { + Fsm_bin_mgr bin_mgr = mnt_itm.Bin_mgr(); + int bin_len = bin_mgr.Dbs__len(); + for (int i = 0; i < bin_len; ++i) { + Fsm_bin_fil bin_fil = bin_mgr.Dbs__get_at(i); + Io_url bin_fil_url = bin_fil.Url(); + + // ignore if bin_fil is earlier than cutoff + if (pack_file_cutoff != null) { + DateAdp bin_fil_date = Io_mgr.Instance.QueryFil(bin_fil_url).ModifiedTime(); + if (bin_fil_date.Timestamp_unix() < pack_file_cutoff.Timestamp_unix()) continue; + } + rv.Add(zip_name_bldr, Xobc_import_type.Tid__file__data, bin_fil_url); + } } } return rv; diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/files/cmds/Xobldr__lnki_temp__create.java b/400_xowa/src/gplx/xowa/addons/bldrs/files/cmds/Xobldr__lnki_temp__create.java index 365fb6ddd..6f325aa6b 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/files/cmds/Xobldr__lnki_temp__create.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/files/cmds/Xobldr__lnki_temp__create.java @@ -26,7 +26,7 @@ import gplx.fsdb.meta.*; import gplx.xowa.files.fsdb.*; import gplx.fsdb.*; import gplx.xowa.langs.vnts.*; import gplx.xowa.parsers.vnts.*; import gplx.xowa.parsers.lnkis.files.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*; import gplx.xowa.bldrs.wkrs.*; -import gplx.xowa.addons.bldrs.files.dbs.*; +import gplx.xowa.addons.bldrs.files.dbs.*; import gplx.xowa.addons.bldrs.mass_parses.parses.*; public class Xobldr__lnki_temp__create extends Xob_dump_mgr_base implements gplx.xowa.parsers.lnkis.files.Xop_file_logger { private Xob_lnki_temp_tbl tbl; private boolean wdata_enabled = true, xtn_ref_enabled = true, gen_html, gen_hdump; private Xop_log_invoke_wkr invoke_wkr; private Xop_log_property_wkr property_wkr; @@ -140,7 +140,7 @@ public class Xobldr__lnki_temp__create extends Xob_dump_mgr_base implements gplx Xof_ext ext = Xof_ext_.new_by_ttl_(ttl); double lnki_time = lnki.Time(); int lnki_page = lnki.Page(); - byte[] ttl_commons = Xto_commons(ns_file_is_case_match_all, commons_wiki, ttl); + byte[] ttl_commons = Xomp_file_logger.To_commons_ttl(ns_file_is_case_match_all, commons_wiki, ttl); if ( Xof_lnki_page.Null_n(lnki_page) // page set && Xof_lnki_time.Null_n(lnki_time)) // thumbtime set usr_dlg.Warn_many("", "", "page and thumbtime both set; this may be an issue with fsdb: page=~{0} ttl=~{1}", ctx.Page().Ttl().Page_db_as_str(), String_.new_u8(ttl)); @@ -177,11 +177,5 @@ public class Xobldr__lnki_temp__create extends Xob_dump_mgr_base implements gplx if (property_wkr == null) property_wkr = bldr.App().Wiki_mgr().Wdata_mgr().Property_wkr_or_new(); return property_wkr; } - public static byte[] Xto_commons(boolean ns_file_is_case_match_all, Xowe_wiki commons_wiki, byte[] ttl_bry) { - if (!ns_file_is_case_match_all) return null; // return "" if wiki matches common - Xoa_ttl ttl = Xoa_ttl.Parse(commons_wiki, Xow_ns_.Tid__file, ttl_bry); - byte[] rv = ttl.Page_db(); - return Bry_.Eq(rv, ttl_bry) ? null : rv; - } public static boolean Ns_file_is_case_match_all(Xow_wiki wiki) {return wiki.Ns_mgr().Ns_file().Case_match() == Xow_ns_case_.Tid__all;} } diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/files/cmds/Xobldr__lnki_temp__create__tst.java b/400_xowa/src/gplx/xowa/addons/bldrs/files/cmds/Xobldr__lnki_temp__create__tst.java index beaf75816..b6a09e1bd 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/files/cmds/Xobldr__lnki_temp__create__tst.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/files/cmds/Xobldr__lnki_temp__create__tst.java @@ -38,6 +38,6 @@ class Xobldr__lnki_temp__create__fxt { return this; } public void Test__to_commons(String ttl, String expd) { - Tfds.Eq(expd, String_.new_u8(Xobldr__lnki_temp__create.Xto_commons(wiki_ns_file_is_case_match_all, commons_wiki, Bry_.new_u8(ttl)))); + Tfds.Eq(expd, String_.new_u8(gplx.xowa.addons.bldrs.mass_parses.parses.Xomp_file_logger.To_commons_ttl(wiki_ns_file_is_case_match_all, commons_wiki, Bry_.new_u8(ttl)))); } } diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/files/dbs/Xob_lnki_temp_tbl.java b/400_xowa/src/gplx/xowa/addons/bldrs/files/dbs/Xob_lnki_temp_tbl.java index 13b8a718d..8ae8a5ace 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/files/dbs/Xob_lnki_temp_tbl.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/files/dbs/Xob_lnki_temp_tbl.java @@ -17,9 +17,9 @@ along with this program. If not, see . */ package gplx.xowa.addons.bldrs.files.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.files.*; import gplx.dbs.*; import gplx.xowa.files.*; -public class Xob_lnki_temp_tbl { +public class Xob_lnki_temp_tbl implements Db_tbl { private static final Dbmeta_fld_list flds = new Dbmeta_fld_list(); - private static final String Tbl_name = "lnki_temp"; + private static final String tbl_name = "lnki_temp"; public static final String Fld_lnki_id = flds.Add_int_pkey_autonum("lnki_id"); // NOTE: insertion order index; public b/c not used and want to bypass warning private static final String @@ -39,8 +39,9 @@ public class Xob_lnki_temp_tbl { private Db_stmt stmt_insert; public Xob_lnki_temp_tbl(Db_conn conn) {this.conn = conn;} public Db_conn Conn() {return conn;} private final Db_conn conn; - public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(Tbl_name, flds));} - public void Insert_bgn() {conn.Txn_bgn("bldr__lnki_temp"); stmt_insert = conn.Stmt_insert(Tbl_name, flds);} + public String Tbl_name() {return tbl_name;} + public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));} + public void Insert_bgn() {conn.Txn_bgn("bldr__lnki_temp"); stmt_insert = conn.Stmt_insert(tbl_name, flds);} public void Insert_commit() {conn.Txn_sav();} public void Insert_end() {conn.Txn_end(); stmt_insert = Db_stmt_.Rls(stmt_insert);} public void Insert_cmd_by_batch(int tier_id, int page_id, byte[] ttl, byte[] ttl_commons, byte ext_id, byte img_type, byte lnki_src_tid, int w, int h, double upright, double time, int page) { @@ -59,4 +60,5 @@ public class Xob_lnki_temp_tbl { .Val_int (Fld_lnki_page , page) .Exec_insert(); } + public void Rls() {} } diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/dbs/Xomp_db_core.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/dbs/Xomp_db_core.java index 8152b39e3..9b5107dee 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/dbs/Xomp_db_core.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/dbs/Xomp_db_core.java @@ -25,6 +25,7 @@ public class Xomp_db_core { Io_url mgr_url = root_dir.GenSubFil("xomp.sqlite3"); this.mgr_db = new Xomp_mgr_db(mgr_url); } + public Db_conn Conn() {return mgr_db.Conn();} public Xomp_mgr_db Mgr_db() {return mgr_db;} private Xomp_mgr_db mgr_db; public Xomp_wkr_db Wkr_db(boolean delete, int idx) { Io_url wkr_url = root_dir.GenSubFil_nest("xomp_" + Int_.To_str_fmt(idx, "000"), "xomp_wkr.sqlite3"); diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/dbs/Xomp_page_tbl.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/dbs/Xomp_page_tbl.java index 46590f018..f36b7ee96 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/dbs/Xomp_page_tbl.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/dbs/Xomp_page_tbl.java @@ -23,7 +23,8 @@ public class Xomp_page_tbl implements Db_tbl { public Xomp_page_tbl(Db_conn conn) { this.conn = conn; this.tbl_name = "xomp_page"; - flds.Add_int_pkey("page_id"); + flds.Add_int_pkey("xomp_uid"); + flds.Add_int("page_id"); flds.Add_int("page_ns"); flds.Add_byte("page_status"); // 0=wait; 1=done; 2=fail flds.Add_int_dflt("html_len", -1); @@ -33,7 +34,11 @@ public class Xomp_page_tbl implements Db_tbl { public String Tbl_name() {return tbl_name;} private final String tbl_name; public Dbmeta_fld_list Flds() {return flds;} private final Dbmeta_fld_list flds = new Dbmeta_fld_list(); public void Create_tbl() { - conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds)); + conn.Meta_tbl_create + ( Dbmeta_tbl_itm.New(tbl_name, flds + , Dbmeta_idx_itm.new_normal_by_tbl("xomp_page", "xomp_uid__page_status" , "xomp_uid", "page_status")// for parse + , Dbmeta_idx_itm.new_normal_by_tbl("xomp_page", "page_ns__page_id" , "page_ns", "page_id") // for make + )); } public void Rls() {} } diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xob_lnki_temp_row.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xob_lnki_temp_row.java new file mode 100644 index 000000000..f33eb2343 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xob_lnki_temp_row.java @@ -0,0 +1,57 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.mass_parses.makes; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*; +import gplx.dbs.*; +class Xob_lnki_temp_row implements CompareAble { + public int Xomp_uid() {return xomp_uid;} private int xomp_uid; + public int Make_uid() {return make_uid;} private int make_uid; + public int Lnki_tier_id() {return lnki_tier_id;} private int lnki_tier_id; + public int Lnki_page_id() {return lnki_page_id;} private int lnki_page_id; + public byte[] Lnki_ttl() {return lnki_ttl;} private byte[] lnki_ttl; + public byte[] Lnki_commons_ttl() {return lnki_commons_ttl;} private byte[] lnki_commons_ttl; + public byte Lnki_ext() {return lnki_ext;} private byte lnki_ext; + public byte Lnki_type() {return lnki_type;} private byte lnki_type; + public byte Lnki_src_tid() {return lnki_src_tid;} private byte lnki_src_tid; + public int Lnki_w() {return lnki_w;} private int lnki_w; + public int Lnki_h() {return lnki_h;} private int lnki_h; + public double Lnki_upright() {return lnki_upright;} private double lnki_upright; + public double Lnki_time() {return lnki_time;} private double lnki_time; + public int Lnki_page() {return lnki_page;} private int lnki_page; + public void Load(Db_rdr rdr, int xomp_uid) { + this.xomp_uid = xomp_uid; + this.make_uid = rdr.Read_int("lnki_make_uid"); + this.lnki_tier_id = rdr.Read_int("lnki_tier_id"); + this.lnki_page_id = rdr.Read_int("lnki_page_id"); + this.lnki_ttl = rdr.Read_bry_by_str("lnki_ttl"); + this.lnki_commons_ttl = rdr.Read_bry_by_str("lnki_commons_ttl"); + this.lnki_ext = rdr.Read_byte("lnki_ext"); + this.lnki_type = rdr.Read_byte("lnki_type"); + this.lnki_src_tid = rdr.Read_byte("lnki_src_tid"); + this.lnki_w = rdr.Read_int("lnki_w"); + this.lnki_h = rdr.Read_int("lnki_h"); + this.lnki_upright = rdr.Read_double("lnki_upright"); + this.lnki_time = rdr.Read_int("lnki_time"); + this.lnki_page = rdr.Read_int("lnki_page"); + } + public int compareTo(Object obj) { + Xob_lnki_temp_row comp = (Xob_lnki_temp_row)obj; + int rv = Int_.Compare(xomp_uid, comp.xomp_uid); + if (rv != CompareAble_.Same) return rv; + return Int_.Compare(make_uid, comp.make_uid); + } +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xomp_html_db_wtr.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xomp_html_db_wtr.java index b793c627e..d3496ff79 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xomp_html_db_wtr.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xomp_html_db_wtr.java @@ -33,24 +33,33 @@ class Xomp_html_db_wtr { public int Cur_db_id() {return html_db.Id();} public Xowd_html_tbl Tbls__get_or_new(int ns_id, long html_len) { long len_new = len_cur + html_len; - if (html_tbl == null || len_new > len_max) { - Commit(); - this.html_db = wiki.Data__core_mgr().Dbs__get_by_tid_or_null(Xow_db_file_.Tid__html_data); - if (html_db == null) { - html_db = wiki.Data__core_mgr().Dbs__make_by_tid(Xow_db_file_.Tid__html_data); - html_db.Conn().Txn_bgn("xomp.html_db_wtr"); - this.html_tbl = new Xowd_html_tbl(html_db.Conn()); - html_tbl.Create_tbl(); + boolean not_inited = html_tbl == null, out_of_space = len_new > len_max; + if (not_inited || out_of_space) { + if (out_of_space) + Commit(); + if ( db_mgr.Props().Layout_html().Tid_is_all_or_few() // is not "lot" + && not_inited // not_inited; set html_db + ) { + this.html_db = wiki.Data__core_mgr().Dbs__get_by_tid_or_null(Xow_db_file_.Tid__html_data); + if (html_db == null) + this.html_db = wiki.Data__core_mgr().Dbs__make_by_tid(Xow_db_file_.Tid__html_data); } + else + this.html_db = wiki.Data__core_mgr().Dbs__make_by_tid(Xow_db_file_.Tid__html_data); + + this.html_tbl = new Xowd_html_tbl(html_db.Conn()); + html_tbl.Create_tbl(); + html_db.Conn().Txn_bgn("xomp.html_db_wtr"); + len_cur = html_len; // NOTE: this effectively resets len_new to 0 + html_len; } - len_cur = len_new; + else // initied and still has space; just update len + len_cur = len_new; return html_tbl; } public void Rls() { this.Commit(); } private void Commit() { - if (html_tbl == null) return; html_tbl.Conn().Txn_end(); html_tbl.Conn().Rls_conn(); diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xomp_make_lnki.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xomp_make_lnki.java new file mode 100644 index 000000000..34a216055 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/makes/Xomp_make_lnki.java @@ -0,0 +1,95 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.mass_parses.makes; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*; +import gplx.core.brys.*; +import gplx.dbs.*; import gplx.xowa.htmls.core.dbs.*; import gplx.xowa.addons.bldrs.mass_parses.dbs.*; import gplx.xowa.addons.bldrs.files.dbs.*; +import gplx.xowa.bldrs.*; +class Xomp_make_lnki { + public void Exec(Xowe_wiki wiki, int uid_count) { + // init + Xomp_db_core xomp_db = Xomp_db_core.New__load(wiki); + + Xob_db_file make_db = Xob_db_file.New__file_make(wiki.Fsys_mgr().Root_dir()); + Xob_lnki_temp_tbl lnki_temp_tbl = new Xob_lnki_temp_tbl(make_db.Conn()); + lnki_temp_tbl.Insert_bgn(); + + // add index + int wkr_count = xomp_db.Wkr_count(); + for (int i = 0; i < wkr_count; ++i) { + Xomp_wkr_db wkr_db = xomp_db.Wkr_db(Bool_.N, i); + wkr_db.Conn().Meta_idx_assert("lnki_temp", "lnki_page_id", "lnki_page_id"); + } + + // loop + List_adp rows = List_adp_.New(); + int uid_bgn = -1; + while (true) { + int count = 0; + for (int i = 0; i < wkr_count; ++i) { + Xomp_wkr_db wkr_db = xomp_db.Wkr_db(Bool_.N, i); + count += Load_rows(rows, xomp_db, wkr_db, uid_bgn, uid_bgn + uid_count); + } + if (count == 0) break; + Save_rows(rows, lnki_temp_tbl); + } + + // term + lnki_temp_tbl.Insert_end(); + xomp_db.Conn().Rls_conn(); + make_db.Conn().Rls_conn(); + } + private int Load_rows(List_adp rows, Xomp_db_core xomp_db, Xomp_wkr_db wkr_db, int uid_bgn, int uid_end) { + // build sql + Db_attach_mgr attach_mgr = new Db_attach_mgr(xomp_db.Conn()); + attach_mgr.Conn_others_(new Db_attach_itm("wkr_db", wkr_db.Conn())); + String sql = String_.Format(String_.Concat_lines_nl_skip_last + ( "SELECT mgr.xomp_uid" + , ", wkr.*" + , "FROM lnki_temp wkr" + , " JOIN xomp_page mgr ON wkr.lnki_page_id = mgr.page_id" + , "WHERE mgr.xomp_uid > {0} AND mgr.xomp_uid <= {1}" + ) + , uid_bgn + , uid_end + ); + sql = attach_mgr.Resolve_sql(sql); + + attach_mgr.Attach(); + Db_rdr rdr = xomp_db.Conn().Stmt_sql(sql).Exec_select__rls_auto(); // ANSI.Y + int rv = -1; + try { + while (rdr.Move_next()) { + rv = rdr.Read_int("xomp_uid"); + Xob_lnki_temp_row row = new Xob_lnki_temp_row(); + row.Load(rdr, rv); + } + } finally {rdr.Rls();} + attach_mgr.Detach(); + return rv; + } + + private void Save_rows(List_adp rows, Xob_lnki_temp_tbl lnki_temp_tbl) { + int len = rows.Len(); + for (int i = 0; i < len; ++i) { + Xob_lnki_temp_row row = (Xob_lnki_temp_row)rows.Get_at(i); + lnki_temp_tbl.Insert_cmd_by_batch(row.Lnki_tier_id(), row.Lnki_page_id(), row.Lnki_ttl(), row.Lnki_commons_ttl() + , row.Lnki_ext(), row.Lnki_src_tid(), row.Lnki_src_tid(), row.Lnki_w(), row.Lnki_h(), row.Lnki_upright() + , row.Lnki_time(), row.Lnki_page()); + } + } +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_file_logger.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_file_logger.java new file mode 100644 index 000000000..ac131ed87 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_file_logger.java @@ -0,0 +1,58 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.mass_parses.parses; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*; +import gplx.dbs.*; +import gplx.xowa.parsers.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.lnkis.files.*; +import gplx.xowa.files.*; import gplx.xowa.addons.bldrs.files.cmds.*; import gplx.xowa.addons.bldrs.files.dbs.*; +import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.domains.*; +public class Xomp_file_logger implements Xop_file_logger { + private final Xob_lnki_temp_tbl tbl; + private final Xowe_wiki commons_wiki; + private boolean ns_file_is_case_match_all = true; + public Xomp_file_logger(Xowe_wiki wiki, Db_conn wkr_conn) { + this.tbl = new Xob_lnki_temp_tbl(wkr_conn); wkr_conn.Meta_tbl_assert(tbl); + this.commons_wiki = wiki.Appe().Wiki_mgr().Get_by_or_make(Xow_domain_itm_.Bry__commons); + this.ns_file_is_case_match_all = wiki.Init_assert().Ns_mgr().Ns_file().Case_match() == Xow_ns_case_.Tid__all; // NOTE: wiki must be init'd; + } + public void Bgn() { + tbl.Insert_bgn(); + } + public void Log_file(Xop_ctx ctx, Xop_lnki_tkn lnki, byte caller_tid) { + if (lnki.Ttl().ForceLiteralLink()) return; // ignore literal links which create a link to file, but do not show the image; EX: [[:File:A.png|thumb|120px]] creates a link to File:A.png, regardless of other display-oriented args + + // get caller_tid / tttl + if (lnki.Ns_id() == Xow_ns_.Tid__media) caller_tid = Xop_file_logger_.Tid__media; + + // get lnki_data + byte[] ttl = lnki.Ttl().Page_db(); + Xof_ext ext = Xof_ext_.new_by_ttl_(ttl); + byte[] ttl_commons = Xomp_file_logger.To_commons_ttl(ns_file_is_case_match_all, commons_wiki, ttl); + + // do insert + tbl.Insert_cmd_by_batch(ctx.Page().Bldr__ns_ord(), ctx.Page().Db().Page().Id(), ttl, ttl_commons, Byte_.By_int(ext.Id()), lnki.Lnki_type(), caller_tid, lnki.W(), lnki.H(), lnki.Upright(), lnki.Time(), lnki.Page()); + } + public void End() { + tbl.Insert_end(); + } + public static byte[] To_commons_ttl(boolean ns_file_is_case_match_all, Xowe_wiki commons_wiki, byte[] ttl_bry) { // handle case-sensitive wikis (en.d) vs case-insensitive commons + if (!ns_file_is_case_match_all) return null; // return "" if wiki matches common + Xoa_ttl ttl = Xoa_ttl.Parse(commons_wiki, Xow_ns_.Tid__file, ttl_bry); + byte[] rv = ttl.Page_db(); + return Bry_.Eq(rv, ttl_bry) ? null : rv; + } +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_page_pool_loader.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_page_pool_loader.java index 588bff101..ac80dbef2 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_page_pool_loader.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_page_pool_loader.java @@ -21,7 +21,7 @@ class Xomp_page_pool_loader { private final Xow_wiki wiki; private final int num_pages_per_load; private final Db_attach_mgr attach_mgr; - private int prv_page_id = -1; + private int prv_uid = -1; public Xomp_page_pool_loader(Xow_wiki wiki, Db_conn make_conn, int num_pages_per_load) { this.wiki = wiki; this.make_conn = make_conn; @@ -49,16 +49,17 @@ class Xomp_page_pool_loader { private void Load_from_db(List_adp list) { // prepare for page_tbl String sql = String_.Format(String_.Concat_lines_nl_skip_last // ANSI.Y - ( "SELECT mp.page_id" + ( "SELECT mp.xomp_uid" + , ", pp.page_id" , ", pp.page_namespace" , ", pp.page_title" , ", pp.page_text_db_id" , "FROM xomp_page mp" , " JOIN page pp ON mp.page_id = pp.page_id" - , "WHERE mp.page_id > {0}" + , "WHERE mp.xomp_uid > {0}" , "AND mp.page_status = 0" , "LIMIT {1}" - ), prv_page_id, num_pages_per_load); + ), prv_uid, num_pages_per_load); this.attach_mgr.Conn_others_(new Db_attach_itm("page_db", wiki.Data__core_mgr().Db__core().Conn())); sql = attach_mgr.Resolve_sql(sql); @@ -68,9 +69,9 @@ class Xomp_page_pool_loader { Db_rdr rdr = make_conn.Stmt_sql(sql).Exec_select__rls_auto(); try { while (rdr.Move_next()) { - prv_page_id = rdr.Read_int("page_id"); + prv_uid = rdr.Read_int("xomp_uid"); int text_db_id = rdr.Read_int("page_text_db_id"); - Xomp_page_itm ppg = new Xomp_page_itm(prv_page_id); + Xomp_page_itm ppg = new Xomp_page_itm(rdr.Read_int("page_id")); ppg.Init_by_page ( rdr.Read_int("page_namespace") , rdr.Read_bry_by_str("page_title") diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_mgr.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_mgr.java index 4d39ed862..7d007f6ee 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_mgr.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.addons.bldrs.mass_parses.parses; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*; -import gplx.core.threads.*; import gplx.core.threads.utils.*; +import gplx.core.threads.*; import gplx.core.threads.utils.*; import gplx.core.caches.*; import gplx.xowa.langs.*; import gplx.xowa.langs.cases.*; import gplx.xowa.addons.bldrs.mass_parses.dbs.*; import gplx.xowa.wikis.caches.*; @@ -32,9 +32,11 @@ class Xomp_parse_mgr { this.db_core = Xomp_db_core.New__load(wiki); Xomp_page_pool_loader pool_loader = new Xomp_page_pool_loader(wiki, db_core.Mgr_db().Conn(), cfg.Num_pages_in_pool()); Xomp_page_pool page_pool = new Xomp_page_pool(pool_loader, cfg.Num_pages_per_wkr()); - prog_mgr.Init(pool_loader.Get_pending_count()); - Xow_page_cache page_cache = Xomp_tmpl_cache_bldr.New(wiki, true); + prog_mgr.Init(pool_loader.Get_pending_count(), cfg.Progress_interval()); wiki.App().User().User_db_mgr().Cache_mgr().Enabled_n_(); // disable db lookups of cache + Xow_page_cache page_cache = Xomp_tmpl_cache_bldr.New(wiki, true); + Gfo_cache_mgr commons_cache = new Gfo_cache_mgr().Max_size_(Int_.Max_value).Reduce_by_(Int_.Max_value); + Gfo_cache_mgr ifexist_cache = new Gfo_cache_mgr().Max_size_(Int_.Max_value).Reduce_by_(Int_.Max_value); // load_wkr: init and start // Xomp_load_wkr load_wkr = new Xomp_load_wkr(wiki, db_core.Mgr_db().Conn(), cfg.Num_pages_in_pool(), cfg.Num_wkrs()); @@ -45,8 +47,13 @@ class Xomp_parse_mgr { latch = new Gfo_countdown_latch(wkr_len); Xomp_parse_wkr[] wkrs = new Xomp_parse_wkr[wkr_len]; for (int i = 0; i < wkr_len; ++i) { - Xomp_parse_wkr wkr = new Xomp_parse_wkr(this, Clone_wiki(wiki), page_pool, i); - wkr.Wiki().Cache_mgr().Page_cache_(page_cache); + Xowe_wiki wkr_wiki = Clone_wiki(wiki); + Xomp_parse_wkr wkr = new Xomp_parse_wkr(this, wkr_wiki, page_pool, i, cfg.Cleanup_interval(), cfg.Progress_interval(), cfg.Log_file_lnkis()); + wkr_wiki.Cache_mgr().Page_cache_(page_cache).Commons_cache_(commons_cache).Ifexist_cache_(ifexist_cache); + // remove wmf wkr, else will try to download images during parsing + if (wkr_wiki.File__bin_mgr() != null) + wkr_wiki.File__bin_mgr().Wkrs__del(gplx.xowa.files.bins.Xof_bin_wkr_.Key_http_wmf); + wkr.Hdump_bldr().Enabled_(cfg.Hdump_enabled()).Hzip_enabled_(cfg.Hzip_enabled()).Hzip_diff_(cfg.Hdiff_enabled()); wkrs[i] = wkr; } diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_mgr_cfg.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_mgr_cfg.java index 094a445d3..181e70319 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_mgr_cfg.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_mgr_cfg.java @@ -17,12 +17,17 @@ along with this program. If not, see . */ package gplx.xowa.addons.bldrs.mass_parses.parses; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*; class Xomp_parse_mgr_cfg implements Gfo_invk { -// public Io_url Root_dir() {return root_dir;} private Io_url root_dir; - public int Num_wkrs() {return num_wkrs;} private int num_wkrs = -1; + public int Num_wkrs() {return num_wkrs;} private int num_wkrs = -1; // use env.available_processors public int Num_pages_in_pool() {return num_pages_in_pool;} private int num_pages_in_pool = 1000; public int Num_pages_per_wkr() {return num_pages_per_wkr;} private int num_pages_per_wkr = 1000; + public int Progress_interval() {return progress_interval;} private int progress_interval = 1000; + public int Commit_interval() {return commit_interval;} private int commit_interval = 10000; + public int Cleanup_interval() {return cleanup_interval;} private int cleanup_interval = 50; // setting at 1000 uses lots of memory + public boolean Hdump_enabled() {return hdump_enabled;} private boolean hdump_enabled = true; + public boolean Hzip_enabled() {return hzip_enabled;} private boolean hzip_enabled = true; + public boolean Hdiff_enabled() {return hdiff_enabled;} private boolean hdiff_enabled = true; + public boolean Log_file_lnkis() {return log_file_lnkis;} private boolean log_file_lnkis = true; public void Init(Xowe_wiki wiki) { -// if (root_dir == null) root_dir = wiki.Fsys_mgr().Root_dir().GenSubDir_nest("tmp", "xomp"); if (num_wkrs == -1) num_wkrs = gplx.core.envs.Env_.System_cpu_count(); } public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { @@ -30,11 +35,18 @@ class Xomp_parse_mgr_cfg implements Gfo_invk { else if (ctx.Match(k, Invk__num_pages_in_pool_)) num_pages_in_pool = m.ReadInt("v"); else if (ctx.Match(k, Invk__num_pages_per_wkr_)) num_pages_per_wkr = m.ReadInt("v"); else if (ctx.Match(k, Invk__num_pages_per_wkr_)) num_pages_per_wkr = m.ReadInt("v"); -// else if (ctx.Match(k, Invk__root_dir_)) root_dir = m.ReadIoUrl("v"); + else if (ctx.Match(k, Invk__progress_interval_)) progress_interval = m.ReadInt("v"); + else if (ctx.Match(k, Invk__commit_interval_)) commit_interval = m.ReadInt("v"); + else if (ctx.Match(k, Invk__cleanup_interval_)) cleanup_interval = m.ReadInt("v"); + else if (ctx.Match(k, Invk__hdump_enabled_)) hdump_enabled = m.ReadBool("v"); + else if (ctx.Match(k, Invk__hzip_enabled_)) hzip_enabled = m.ReadBool("v"); + else if (ctx.Match(k, Invk__hdiff_enabled_)) hdiff_enabled = m.ReadBool("v"); else return Gfo_invk_.Rv_unhandled; return this; } - private static final String Invk__num_wkrs_ = "num_wkrs_", Invk__num_pages_in_pool_ = "num_pages_in_pool_", Invk__num_pages_per_wkr_ = "num_pages_per_wkr_" -// , Invk__root_dir_ = "root_dir_" + private static final String + Invk__num_wkrs_ = "num_wkrs_", Invk__num_pages_in_pool_ = "num_pages_in_pool_", Invk__num_pages_per_wkr_ = "num_pages_per_wkr_" + , Invk__progress_interval_ = "progress_interval_", Invk__commit_interval_ = "commit_interval_", Invk__cleanup_interval_ = "cleanup_interval_" + , Invk__hdump_enabled_ = "hdump_enabled_", Invk__hzip_enabled_ = "hzip_enabled_", Invk__hdiff_enabled_ = "hdiff_enabled_" ; } diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_wkr.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_wkr.java index 65000b7bc..63c1282f2 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_wkr.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_parse_wkr.java @@ -23,23 +23,42 @@ class Xomp_parse_wkr implements Gfo_invk { private final Xomp_parse_mgr mgr; private final Xomp_page_pool page_pool; private final int idx; - private final List_adp list = List_adp_.New(); private int list_idx = 0, list_len = 0; - private final Xob_hdump_bldr hdump_bldr = new Xob_hdump_bldr(); + private final List_adp list = List_adp_.New(); private int list_idx = 0, list_len = 0; private int done_count; private long done_time; - private Xomp_wkr_db wkr_db; - public Xomp_parse_wkr(Xomp_parse_mgr mgr, Xowe_wiki wiki, Xomp_page_pool page_pool, int idx) { + private Xomp_wkr_db wkr_db; private int cleanup_interval, commit_interval; + private boolean log_file_lnkis; + public Xomp_parse_wkr(Xomp_parse_mgr mgr, Xowe_wiki wiki, Xomp_page_pool page_pool, int idx, int cleanup_interval, int commit_interval, boolean log_file_lnkis) { this.mgr = mgr; this.wiki = wiki; this.page_pool = page_pool; this.idx = idx; this.wkr_db = mgr.Db_core().Wkr_db(Bool_.Y, idx); // NOTE: must go in ctor, or else thread issues + this.cleanup_interval = cleanup_interval; + this.commit_interval = commit_interval; + this.log_file_lnkis = log_file_lnkis; } public Xowe_wiki Wiki() {return wiki;} private final Xowe_wiki wiki; + public Xob_hdump_bldr Hdump_bldr() {return hdump_bldr;} private final Xob_hdump_bldr hdump_bldr = new Xob_hdump_bldr(); public void Exec() { // init Xow_parser_mgr parser_mgr = new Xow_parser_mgr(wiki); - wiki.Html_mgr().Page_wtr_mgr().Wkr(gplx.xowa.wikis.pages.Xopg_page_.Tid_read).Ctgs_enabled_(false); // disable categories else progress messages written (also for PERF) - if (wiki.File__bin_mgr() != null) - wiki.File__bin_mgr().Wkrs__del(gplx.xowa.files.bins.Xof_bin_wkr_.Key_http_wmf); // remove wmf wkr, else will try to download images during parsing + + // disable file download + wiki.File_mgr().Init_file_mgr_by_load(wiki); // must happen after fsdb.make + wiki.File__bin_mgr().Wkrs__del(gplx.xowa.files.bins.Xof_bin_wkr_.Key_http_wmf); // must happen after init_file_mgr_by_load; remove wmf wkr, else will try to download images during parsing + wiki.File__orig_mgr().Wkrs_del(gplx.xowa.files.origs.Xof_orig_wkr_.Tid_wmf_api); + + // disable categories else progress messages written (also for PERF) + wiki.Html_mgr().Page_wtr_mgr().Wkr(gplx.xowa.wikis.pages.Xopg_page_.Tid_read).Ctgs_enabled_(false); + + // enable lnki_temp + Xomp_file_logger logger = null; + if (log_file_lnkis) { + logger = new Xomp_file_logger(wiki, wkr_db.Conn()); + parser_mgr.Ctx().Lnki().File_logger_(logger); + logger.Bgn(); + } + + // enable hdump hdump_bldr.Enabled_(true).Hzip_enabled_(true).Hzip_diff_(true).Init(wiki, wkr_db.Conn(), new Xob_hdump_tbl_retriever__xomp(wkr_db.Html_tbl())); wkr_db.Conn().Txn_bgn("xomp"); @@ -76,14 +95,22 @@ class Xomp_parse_wkr implements Gfo_invk { // ctx.App().Utl__bfr_mkr().Clear_fail_check(); // make sure all bfrs are released if (wiki.Cache_mgr().Tmpl_result_cache().Count() > 50000) wiki.Cache_mgr().Tmpl_result_cache().Clear(); - if (done_count % 50 == 0) { + if (done_count % cleanup_interval == 0) { wiki.Cache_mgr().Free_mem_all(Bool_.N); wiki.Parser_mgr().Scrib().Core_term(); + wiki.Appe().Wiki_mgr().Wdata_mgr().Clear(); } + if (done_count % commit_interval == 0) + wkr_db.Conn().Txn_sav(); } catch (Exception e) { Gfo_usr_dlg_.Instance.Warn_many("", "", "mass_parse.fail:ns=~{0} ttl=~{1} err=~{2}", ppg.Ns_id(), ppg.Ttl_bry(), Err_.Message_gplx_log(e)); } } + + if (logger != null) + logger.End(); + + // cleanup wkr_db.Conn().Txn_end(); // NOTE: must end txn before running update wkr_id mgr.Db_core().Update_wkr_id(idx, wkr_db.Conn()); mgr.Wkrs_done_add_1(); diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_prog_mgr.java b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_prog_mgr.java index 2a4a9b6c7..e8f39acfb 100644 --- a/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_prog_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/bldrs/mass_parses/parses/Xomp_prog_mgr.java @@ -18,17 +18,19 @@ along with this program. If not, see . package gplx.xowa.addons.bldrs.mass_parses.parses; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*; class Xomp_prog_mgr { private final Object thread_lock = new Object(); + private int progress_interval; private int pages_done, pages_total; private long time_bgn, time_prv, time_done; private final Bry_bfr prog_bfr = Bry_bfr_.New(); - public void Init(int pages_total) { + public void Init(int pages_total, int progress_interval) { + this.progress_interval = progress_interval; this.time_bgn = this.time_prv = gplx.core.envs.Env_.TickCount(); this.pages_total = pages_total; } public void Mark_done(int id) { synchronized (thread_lock) { pages_done += 1; - if (pages_done % 1000 == 0) { + if (pages_done % progress_interval == 0) { long time_cur = gplx.core.envs.Env_.TickCount(); int pages_left = pages_total - pages_done; time_done += (time_cur - time_prv); diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_addon.java b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_addon.java new file mode 100644 index 000000000..4fdfa126c --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_addon.java @@ -0,0 +1,46 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.xodirs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; +import gplx.xowa.specials.*; +import gplx.xowa.addons.wikis.imports.*; +public class Xobc_xodir_addon implements Xoax_addon_itm, Xoax_addon_itm__special, Xoax_addon_itm__init { + public Xow_special_page[] Special_pages() { + return new Xow_special_page[] + { Xobc_xodir_special.Prototype + }; + } + public void Init_addon_by_app(Xoa_app app) { + } + public void Init_addon_by_wiki(Xow_wiki wiki) { + Xow_import_addon addon = Xow_import_addon.Addon__get(wiki); + addon.Dir_selected_cbks__add(Xow_import_dir_cbk__xodir.Instance); + } + + public String Addon__key() {return ADDON__KEY;} private static final String ADDON__KEY = "xowa.bldrs.xodirs"; +} +class Xow_import_dir_cbk__xodir implements Xow_import_dir_cbk { + public String Key() {return "xodir";} + public void Cbk__dir_selected(Xow_wiki wiki, Xoa_page page, String path) { + // save to prefs + wiki.App().User().User_db_mgr().Cfg().Set_app_str("xowa.xodir.custom_dir", path); + + // redirect to import_dir + page.Redirect().Itms__add__special(wiki, Xobc_xodir_special.Prototype.Special__meta()); + } + public static Xow_import_dir_cbk__xodir Instance = new Xow_import_dir_cbk__xodir(); Xow_import_dir_cbk__xodir() {} +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_cfg.java b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_cfg.java new file mode 100644 index 000000000..156f5698b --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_cfg.java @@ -0,0 +1,30 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.xodirs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; +public class Xobc_xodir_cfg { + public static final String + Key__selected_dir = "xowa.xodir.selected_dir" + , Key__custom_dir = "xowa.xodir.custom_dir" + ; + public static void Set_app_str__selected(Xoa_app app, byte[] val_bry) { + // if wnt, replace "\"; note that url-encoding while navigating dirs will always convert "\" to "/" + if (gplx.core.envs.Op_sys.Cur().Tid_is_wnt()) val_bry = Bry_.Replace(val_bry, Byte_ascii.Slash, Byte_ascii.Backslash); + + app.User().User_db_mgr().Cfg().Set_app_bry(Xobc_xodir_cfg.Key__selected_dir, val_bry); + } +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_dir.java b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_dir.java new file mode 100644 index 000000000..e51932fcc --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_dir.java @@ -0,0 +1,51 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.xodirs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; +import gplx.langs.mustaches.*; +class Xobc_xodir_doc implements Mustache_doc_itm { + private final byte[] import_root, app_root_dir; + private final Xobc_xodir_dir[] dirs; + public Xobc_xodir_doc(Xobc_xodir_dir[] dirs, byte[] import_root, byte[] app_root_dir) { + this.dirs = dirs; this.import_root = import_root; this.app_root_dir = app_root_dir; + } + public boolean Mustache__write(String key, Mustache_bfr bfr) { + if (String_.Eq(key, "import_root")) bfr.Add_bry(import_root); + else if (String_.Eq(key, "app_root_dir")) bfr.Add_bry(app_root_dir); + return false; + } + public Mustache_doc_itm[] Mustache__subs(String key) { + if (String_.Eq(key, "dirs")) return dirs; + return Mustache_doc_itm_.Ary__empty; + } +} +public class Xobc_xodir_dir implements Mustache_doc_itm { + private final boolean is_selected, is_custom; + private final byte[] path; + public Xobc_xodir_dir(boolean is_selected, boolean is_custom, byte[] path) { + this.is_selected = is_selected; this.is_custom = is_custom; this.path = path; + } + public boolean Mustache__write(String key, Mustache_bfr bfr) { + if (String_.Eq(key, "path")) bfr.Add_bry(path); + return false; + } + public Mustache_doc_itm[] Mustache__subs(String key) { + if (String_.Eq(key, "is_selected")) return Mustache_doc_itm_.Ary__bool(is_selected); + else if (String_.Eq(key, "is_custom")) return Mustache_doc_itm_.Ary__bool(is_custom); + return Mustache_doc_itm_.Ary__empty; + } +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_html.java b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_html.java new file mode 100644 index 000000000..bd0991d18 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_html.java @@ -0,0 +1,40 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.xodirs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; +import gplx.xowa.specials.*; import gplx.langs.mustaches.*; import gplx.xowa.wikis.pages.*; import gplx.xowa.wikis.pages.tags.*; +import gplx.xowa.addons.bldrs.centrals.*; import gplx.xowa.addons.bldrs.centrals.dbs.*; import gplx.xowa.addons.bldrs.centrals.dbs.datas.imports.*; import gplx.xowa.addons.bldrs.centrals.hosts.*; +import gplx.xowa.wikis.domains.*; import gplx.core.ios.*; +class Xobc_xodir_html extends Xow_special_wtr__base { + @Override protected Io_url Get_addon_dir(Xoa_app app) {return app.Fsys_mgr().Http_root().GenSubDir_nest("bin", "any", "xowa", "addon", "bldr", "xodir");} + @Override protected Io_url Get_mustache_fil(Io_url addon_dir) {return addon_dir.GenSubFil_nest("bin", "xobc_xodir.mustache.html");} + @Override protected Mustache_doc_itm Bld_mustache_root(Xoa_app app) { + Xobc_task_addon addon = (Xobc_task_addon)app.Addon_mgr().Itms__get_or_null(Xobc_task_addon.ADDON__KEY); + return new Xobc_xodir_doc + ( addon.Xodir_mgr().Get_dirs(app) + , gplx.xowa.addons.wikis.imports.Xow_import_special.Get_root_url() + , app.Fsys_mgr().Root_dir().RawBry() + ); + } + @Override protected void Bld_tags(Xoa_app app, Io_url addon_dir, Xopage_html_data page_data) { + Xopg_tag_mgr head_tags = page_data.Head_tags(); + Xopg_alertify_.Add_tags (head_tags, app.Fsys_mgr().Http_root()); + Xopg_tag_wtr_.Add__xocss (head_tags, app.Fsys_mgr().Http_root()); + Xopg_tag_wtr_.Add__xohelp (head_tags, app.Fsys_mgr().Http_root()); + head_tags.Add(Xopg_tag_itm.New_css_file(addon_dir.GenSubFil_nest("bin", "xobc_xodir.css"))); + } +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_mgr.java b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_mgr.java new file mode 100644 index 000000000..4f0caa02a --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_mgr.java @@ -0,0 +1,21 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.xodirs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; +public interface Xobc_xodir_mgr { + Xobc_xodir_dir[] Get_dirs(Xoa_app app); +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_mgr__pc.java b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_mgr__pc.java new file mode 100644 index 000000000..d92698bbd --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_mgr__pc.java @@ -0,0 +1,32 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.xodirs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; +public class Xobc_xodir_mgr__pc implements Xobc_xodir_mgr { + public Xobc_xodir_mgr__pc(Xoa_app app) { + } + public Xobc_xodir_dir[] Get_dirs(Xoa_app app) { + int len = 2; + String dflt = app.Fsys_mgr().Root_dir().Raw(); + String selected = app.User().User_db_mgr().Cfg().Get_app_str_or(Xobc_xodir_cfg.Key__selected_dir, dflt); + String custom = app.User().User_db_mgr().Cfg().Get_app_str_or(Xobc_xodir_cfg.Key__custom_dir, "(choose your own folder)"); + Xobc_xodir_dir[] rv = new Xobc_xodir_dir[len]; + rv[0] = new Xobc_xodir_dir(String_.Eq(selected, dflt), Bool_.N, Bry_.new_u8(dflt)); + rv[1] = new Xobc_xodir_dir(String_.Eq(selected, custom), Bool_.Y, Bry_.new_u8(custom)); + return rv; + } +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_special.java b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_special.java new file mode 100644 index 000000000..cea4f41ad --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xobc_xodir_special.java @@ -0,0 +1,45 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.xodirs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; +import gplx.xowa.specials.*; import gplx.core.net.*; import gplx.core.net.qargs.*; import gplx.xowa.wikis.pages.*; +import gplx.xowa.addons.bldrs.centrals.*; +import gplx.xowa.addons.wikis.imports.*; +public class Xobc_xodir_special implements Xow_special_page { + public void Special__gen(Xow_wiki wiki, Xoa_page page, Xoa_url url, Xoa_ttl ttl) { + Gfo_qarg_mgr url_args = new Gfo_qarg_mgr().Init(url.Qargs_ary()); + + byte[] path = url_args.Read_bry_or(Bry__path, null); + if (path != null) { // path selected; set cfg and redirect to Download Central + Xobc_xodir_cfg.Set_app_str__selected(wiki.App(), path); + // On_path_selected.Invk(null, -1, "", null); + // page.Redirect().Itms__add__special(wiki, Xobc_task_special.Prototype.Special__meta()); + page.Redirect().Itms__add__special(wiki, Prototype.Special__meta()); + return; + } + + new Xobc_xodir_html().Bld_page_by_mustache(wiki.App(), page, this); + } + private static final byte[] Bry__path = Bry_.new_a7("path"); + + Xobc_xodir_special(Xow_special_meta special__meta) {this.special__meta = special__meta;} + public Xow_special_meta Special__meta() {return special__meta;} private final Xow_special_meta special__meta; + public Xow_special_page Special__clone() {return this;} + public static final Xow_special_page Prototype = new Xobc_xodir_special(Xow_special_meta.New_xo("XowaRootDir", "XOWA Folder Selection")); + + public static Gfo_invk On_path_selected = Gfo_invk_.Noop; +} diff --git a/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xow_import_dir_cbk__xodir.java b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xow_import_dir_cbk__xodir.java new file mode 100644 index 000000000..9a4fb0c9b --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/bldrs/xodirs/Xow_import_dir_cbk__xodir.java @@ -0,0 +1,19 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.bldrs.xodirs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; +import gplx.xowa.addons.wikis.imports.*; diff --git a/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt.java b/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt.java index 5154561ba..bbf8296bd 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt.java @@ -33,7 +33,7 @@ class Xoh_toc_wkr__txt { public void Init(byte[] page_name) {this.page_name = page_name;} public void Calc_anch_text(Xoh_toc_itm rv, byte[] src) { // text within hdr; EX:

Abc

-> Abc int end = src.length; - src = Remove_comment(text_bfr, src, 0, end); + src = Gfh_utl.Del_comments(text_bfr, src, 0, end); end = src.length; tag_rdr.Init(page_name, src, 0, end); try { @@ -115,6 +115,7 @@ class Xoh_toc_wkr__txt { case Gfh_tag_.Id__img: case Gfh_tag_.Id__br: case Gfh_tag_.Id__hr: + case Gfh_tag_.Id__wbr: lhs_is_dangling = true; break; } @@ -151,31 +152,5 @@ class Xoh_toc_wkr__txt { } } - public static byte[] Remove_comment(Bry_bfr tmp, byte[] src, int bgn, int end) { - boolean dirty = false, append_to_eos = true; - int pos = bgn; - while (true) { - int comm_bgn = Bry_find_.Find_fwd(src, Gfh_tag_.Comm_bgn, pos, end); - if (comm_bgn != -1) { // comment found - int tmp_pos = comm_bgn + Gfh_tag_.Comm_bgn_len; - int comm_end = Bry_find_.Find_fwd(src, Gfh_tag_.Comm_end, tmp_pos, end); - if (comm_end == -1) { // dangling - tmp.Add_mid(src, pos, comm_bgn); - append_to_eos = false; - } - else { - dirty = true; - tmp.Add_mid(src, pos, comm_bgn); - pos = comm_end + Gfh_tag_.Comm_end_len; - continue; - } - } - break; - } - if (dirty && append_to_eos) { - tmp.Add_mid(src, pos, end); - } - return dirty ? tmp.To_bry_and_clear() : src; - } private static final byte[] id_trim_ary = Bry_.mask_(256, Byte_ascii.Underline_bry); } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt__basic__tst.java b/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt__basic__tst.java index 3d19eea21..d258cbea3 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt__basic__tst.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt__basic__tst.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.addons.htmls.tocs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*; -import org.junit.*; import gplx.core.tests.*; +import org.junit.*; import gplx.core.tests.*; import gplx.langs.htmls.*; public class Xoh_toc_wkr__txt__basic__tst { @Before public void init() {fxt.Clear();} private final Xoh_toc_wkr__txt__fxt fxt = new Xoh_toc_wkr__txt__fxt(); @Test public void Basic() { @@ -62,6 +62,6 @@ class Xoh_toc_wkr__txt__fxt { } public void Test__remove_comment(String html, String expd) { byte[] html_bry = Bry_.new_u8(html); - Gftest.Eq__str(expd, Xoh_toc_wkr__txt.Remove_comment(tmp, html_bry, 0, html_bry.length)); + Gftest.Eq__str(expd, Gfh_utl.Del_comments(tmp, html_bry, 0, html_bry.length)); } } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt__xnde__tst.java b/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt__xnde__tst.java index 084efd628..5d365b8a8 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt__xnde__tst.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/tocs/Xoh_toc_wkr__txt__xnde__tst.java @@ -34,6 +34,7 @@ public class Xoh_toc_wkr__txt__xnde__tst { @Test public void A__nest() {fxt.Test__both("bcd" , "bcd", "bcd");} @Test public void Br() {fxt.Test__both("a
b" , "ab");} @Test public void Br__dangling() {fxt.Test__both("a
b" , "ab");} + @Test public void Wbr__dangling() {fxt.Test__both("ab" , "ab");} @Test public void H2() {fxt.Test__both("a

b

c" , "abc");} // NOTE: not a valid test; MW actually generates "ab" b/c of tidy; see corresponding edit test; DATE:2016-06-28 @Test public void Li() {fxt.Test__text("a
  • b
c" , "abc");} @Test public void Table() {fxt.Test__text("a
b
c" , "abc");} diff --git a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_addon.java b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_addon.java index 3a3c9b779..b43d50009 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_addon.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_addon.java @@ -18,11 +18,25 @@ along with this program. If not, see . package gplx.xowa.addons.wikis.imports; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.specials.*; public class Xow_import_addon implements Xoax_addon_itm, Xoax_addon_itm__special { + private final Ordered_hash cbks = Ordered_hash_.New(); public Xow_special_page[] Special_pages() { return new Xow_special_page[] { Xow_import_special.Prototype }; } + public void Dir_selected_cbks__add(Xow_import_dir_cbk cbk) { + if (!cbks.Has(cbk.Key())) + cbks.Add(cbk.Key(), cbk); + } + public Xow_import_dir_cbk Dir_selected_cbks__get_by(String key) {return (Xow_import_dir_cbk)cbks.Get_by(key);} - public String Addon__key() {return "xowa.apps.file_browsers";} + public String Addon__key() {return ADDON__KEY;} private static final String ADDON__KEY = "xowa.apps.file_browsers"; + public static Xow_import_addon Addon__get(Xow_wiki wiki) { + Xow_import_addon rv = (Xow_import_addon)wiki.Addon_mgr().Itms__get_or_null(ADDON__KEY); + if (rv == null) { + rv = new Xow_import_addon(); + wiki.Addon_mgr().Itms__add(rv); + } + return rv; + } } diff --git a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_dir_cbk.java b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_dir_cbk.java new file mode 100644 index 000000000..d4448db65 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_dir_cbk.java @@ -0,0 +1,22 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.wikis.imports; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; +public interface Xow_import_dir_cbk { + String Key(); + void Cbk__dir_selected(Xow_wiki wiki, Xoa_page page, String path); +} diff --git a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_doc.java b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_doc.java index 49ae0b31b..dea7aeb7b 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_doc.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_doc.java @@ -21,12 +21,14 @@ import gplx.langs.mustaches.*; class Xow_import_doc implements Mustache_doc_itm { private final boolean is_dir, is_core_xowa; private final byte[] owner_dir_enc, path, name, date, size, color; + private final byte[] dir_cmd; private final Xow_import_doc[] subs; - public Xow_import_doc(boolean is_dir, boolean is_core_xowa, int color, byte[] owner_dir, byte[] path, byte[] name, byte[] date, byte[] size, Xow_import_doc[] subs) { + public Xow_import_doc(boolean is_dir, boolean is_core_xowa, int color, byte[] owner_dir, byte[] path, byte[] name, byte[] date, byte[] size, byte[] dir_cmd, Xow_import_doc[] subs) { this.is_dir = is_dir; this.is_core_xowa = is_core_xowa; this.color = color % 2 == 0 ? Byte_ascii.Num_0_bry : Byte_ascii.Num_1_bry; this.owner_dir_enc = gplx.langs.htmls.encoders.Gfo_url_encoder_.Href.Encode(owner_dir); this.path = path; this.name = name; this.date = date; this.size = size; + this.dir_cmd = dir_cmd; this.subs = subs; } public boolean Mustache__write(String key, Mustache_bfr bfr) { @@ -37,24 +39,27 @@ class Xow_import_doc implements Mustache_doc_itm { else if (String_.Eq(key, "date")) bfr.Add_bry(date); else if (String_.Eq(key, "size")) bfr.Add_bry(size); else if (String_.Eq(key, "color")) bfr.Add_bry(color); + else if (String_.Eq(key, "dir_cmd")) bfr.Add_bry(dir_cmd); + else if (String_.Eq(key, "dir_cmd_arg")) {bfr.Add_str_u8("&dir_cmd="); bfr.Add_bry(dir_cmd);} else return false; return true; } public Mustache_doc_itm[] Mustache__subs(String key) { if (String_.Eq(key, "is_dir")) return Mustache_doc_itm_.Ary__bool(is_dir); + else if (String_.Eq(key, "dir_cmd_exists")) return Mustache_doc_itm_.Ary__bool(Bry_.Len_gt_0(dir_cmd)); else if (String_.Eq(key, "is_core_xowa")) return Mustache_doc_itm_.Ary__bool(is_core_xowa); else if (String_.Eq(key, "subs")) return subs; return Mustache_doc_itm_.Ary__empty; } public static final Xow_import_doc[] Ary_empty = new Xow_import_doc[0]; - public static Xow_import_doc New(IoItmDir owner_dir) { + public static Xow_import_doc New(IoItmDir owner_dir, byte[] dir_cmd) { List_adp sub_list = List_adp_.New(); - New_subs(owner_dir.Url(), sub_list, owner_dir.SubDirs()); - New_subs(owner_dir.Url(), sub_list, owner_dir.SubFils()); + New_subs(owner_dir.Url(), sub_list, owner_dir.SubDirs(), dir_cmd); + New_subs(owner_dir.Url(), sub_list, owner_dir.SubFils(), Bry_.Empty); Xow_import_doc[] subs = (Xow_import_doc[])sub_list.To_ary_and_clear(Xow_import_doc.class); - return new Xow_import_doc(Bool_.Y, Bool_.N, 0, owner_dir.Url().OwnerDir().RawBry(), owner_dir.Url().RawBry(), Bry_.new_u8(owner_dir.Name()), Bry_.Empty, Bry_.Empty, subs); + return new Xow_import_doc(Bool_.Y, Bool_.N, 0, owner_dir.Url().OwnerDir().RawBry(), owner_dir.Url().RawBry(), Bry_.new_u8(owner_dir.Name()), Bry_.Empty, Bry_.Empty, dir_cmd, subs); } - private static void New_subs(Io_url owner_dir, List_adp list, IoItmList subs) { + private static void New_subs(Io_url owner_dir, List_adp list, IoItmList subs, byte[] dir_cmd) { subs.Sort(); int len = subs.Len(); int list_total = list.Len(); @@ -64,13 +69,13 @@ class Xow_import_doc implements Mustache_doc_itm { Xow_import_doc trg = null; if (src.Type_dir()) { byte[] trg_url = src.Url().RawBry(); - trg = new Xow_import_doc(Bool_.Y, Bool_.N, list_total + i, owner_dir_bry, trg_url, Bry_.new_u8(src.Url().NameAndExt_noDirSpr()), Bry_.Empty, Bry_.Empty, Ary_empty); + trg = new Xow_import_doc(Bool_.Y, Bool_.N, list_total + i, owner_dir_bry, trg_url, Bry_.new_u8(src.Url().NameAndExt_noDirSpr()), Bry_.Empty, Bry_.Empty, dir_cmd, Ary_empty); } else { IoItmFil src_as_fil = (IoItmFil)src; String size_str = Io_size_.To_str(src_as_fil.Size(), "#,###"); boolean is_xowa_core = gplx.xowa.wikis.data.Xow_db_file__core_.Is_core_fil_name(owner_dir.NameOnly(), src.Url().NameAndExt()); - trg = new Xow_import_doc(Bool_.N, is_xowa_core, list_total + i, owner_dir_bry, src.Url().RawBry(), Bry_.new_u8(src.Name()), Bry_.new_u8(src_as_fil.ModifiedTime().XtoStr_fmt("yyyy-MM-dd")), Bry_.new_u8(size_str), Ary_empty); + trg = new Xow_import_doc(Bool_.N, is_xowa_core, list_total + i, owner_dir_bry, src.Url().RawBry(), Bry_.new_u8(src.Name()), Bry_.new_u8(src_as_fil.ModifiedTime().XtoStr_fmt("yyyy-MM-dd")), Bry_.new_u8(size_str), dir_cmd, Ary_empty); } list.Add(trg); } diff --git a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_html.java b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_html.java index 72305deec..ab455645d 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_html.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_html.java @@ -19,13 +19,16 @@ package gplx.xowa.addons.wikis.imports; import gplx.*; import gplx.xowa.*; impor import gplx.xowa.specials.*; import gplx.langs.mustaches.*; import gplx.xowa.wikis.pages.*; import gplx.xowa.wikis.pages.tags.*; import gplx.core.ios.*; class Xow_import_html extends Xow_special_wtr__base { - private final Io_url owner_url; - public Xow_import_html(Io_url owner_url) {this.owner_url = owner_url;} + private final Io_url owner_url; private final byte[] mode; + public Xow_import_html(Io_url owner_url, byte[] mode) { + this.owner_url = owner_url; + this.mode = mode; + } @Override protected Io_url Get_addon_dir(Xoa_app app) {return app.Fsys_mgr().Http_root().GenSubDir_nest("bin", "any", "xowa", "addon", "wiki", "import");} @Override protected Io_url Get_mustache_fil(Io_url addon_dir) {return addon_dir.GenSubFil_nest("bin", "xow_import.mustache.html");} @Override protected Mustache_doc_itm Bld_mustache_root(Xoa_app app) { IoItmDir owner_dir = Io_mgr.Instance.QueryDir_args(owner_url).DirInclude_(true).ExecAsDir(); - return Xow_import_doc.New(owner_dir); + return Xow_import_doc.New(owner_dir, mode); } @Override protected void Bld_tags(Xoa_app app, Io_url addon_dir, Xopage_html_data page_data) { Xopg_tag_mgr head_tags = page_data.Head_tags(); diff --git a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_special.java b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_special.java index 8bec57af3..5fd6cb242 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_special.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/imports/Xow_import_special.java @@ -29,7 +29,29 @@ public class Xow_import_special implements Xow_special_page { return; } - new Xow_import_html(Io_url_.new_dir_(owner_str)).Bld_page_by_mustache(wiki.App(), page, this); + // check if dir_cmd is available + byte[] dir_cmd = url_args.Read_bry_or_null("dir_cmd"); + + // check selected + int selected = url_args.Read_int_or("selected", -1); + if ( selected == 1 + && dir_cmd != null) { + Xow_import_addon addon = Xow_import_addon.Addon__get(wiki); + Xow_import_dir_cbk import_cbk = addon.Dir_selected_cbks__get_by(String_.new_u8(dir_cmd)); + import_cbk.Cbk__dir_selected(wiki, page, owner_str); + } + + new Xow_import_html(Io_url_.new_dir_(owner_str), dir_cmd).Bld_page_by_mustache(wiki.App(), page, this); + } + + public static byte[] Get_root_url() { + byte tid = gplx.core.envs.Op_sys.Cur().Tid(); + byte[] rv = Bry_.new_a7("/"); + switch (tid) { + case gplx.core.envs.Op_sys.Tid_wnt : rv = Bry_.new_a7("C:\\"); break; + } + rv = gplx.langs.htmls.encoders.Gfo_url_encoder_.Href.Encode(rv); + return rv; } Xow_import_special(Xow_special_meta special__meta) {this.special__meta = special__meta;} diff --git a/400_xowa/src/gplx/xowa/addons/wikis/registrys/infos/Xow_info_special.java b/400_xowa/src/gplx/xowa/addons/wikis/registrys/infos/Xow_info_special.java index f23dcc4be..75206ca18 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/registrys/infos/Xow_info_special.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/registrys/infos/Xow_info_special.java @@ -31,8 +31,7 @@ public class Xow_info_special implements Xow_special_page { delete_wiki.Data__core_mgr().Rls(); // release connection if open Delete_wiki_files(delete_wiki.Fsys_mgr().Root_dir()); } - Xoa_ttl redirect_ttl = wiki.Ttl_parse(gplx.xowa.addons.wikis.registrys.lists.Xow_list_special.Prototype.Special__meta().Ttl_bry()); - page.Redirect().Itms__add__special(Xoa_url.New(wiki, redirect_ttl), redirect_ttl); + page.Redirect().Itms__add__special(wiki, gplx.xowa.addons.wikis.registrys.lists.Xow_list_special.Prototype.Special__meta()); return; } diff --git a/400_xowa/src/gplx/xowa/addons/wikis/registrys/lists/Xow_list_html.java b/400_xowa/src/gplx/xowa/addons/wikis/registrys/lists/Xow_list_html.java index 1a9648a7d..406b4d7f6 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/registrys/lists/Xow_list_html.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/registrys/lists/Xow_list_html.java @@ -33,7 +33,7 @@ class Xow_list_html extends Xow_special_wtr__base { if (String_.Eq(site_itm.Domain(), gplx.xowa.wikis.domains.Xow_domain_itm_.Str__home)) continue; list.Add(new Xow_list_doc_wiki(Bry_.new_u8(site_itm.Domain()), site_itm.Date())); } - return new Xow_list_doc(Get_root_url(), (Xow_list_doc_wiki[])list.To_ary_and_clear(Xow_list_doc_wiki.class)); + return new Xow_list_doc(gplx.xowa.addons.wikis.imports.Xow_import_special.Get_root_url(), (Xow_list_doc_wiki[])list.To_ary_and_clear(Xow_list_doc_wiki.class)); } @Override protected void Bld_tags(Xoa_app app, Io_url addon_dir, Xopage_html_data page_data) { Xopg_tag_mgr head_tags = page_data.Head_tags(); @@ -41,13 +41,4 @@ class Xow_list_html extends Xow_special_wtr__base { Xopg_tag_wtr_.Add__xohelp (head_tags, app.Fsys_mgr().Http_root()); head_tags.Add(Xopg_tag_itm.New_css_file(addon_dir.GenSubFil_nest("bin", "xow_list.css"))); } - private static byte[] Get_root_url() { - byte tid = gplx.core.envs.Op_sys.Cur().Tid(); - byte[] rv = Bry_.new_a7("/"); - switch (tid) { - case gplx.core.envs.Op_sys.Tid_wnt : rv = Bry_.new_a7("C:\\"); break; - } - rv = gplx.langs.htmls.encoders.Gfo_url_encoder_.Href.Encode(rv); - return rv; - } } diff --git a/400_xowa/src/gplx/xowa/addons/wikis/searchs/bldrs/Srch_temp_tbl_wkr.java b/400_xowa/src/gplx/xowa/addons/wikis/searchs/bldrs/Srch_temp_tbl_wkr.java index 950872499..7f564b692 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/searchs/bldrs/Srch_temp_tbl_wkr.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/searchs/bldrs/Srch_temp_tbl_wkr.java @@ -82,7 +82,7 @@ class Srch_temp_tbl_wkr implements Srch_text_parser_wkr { Db_attach_mgr attach_mgr = new Db_attach_mgr(); // dump everything into a temp table in order to index it - page_conn.Meta_idx_create(Dbmeta_idx_itm.new_normal_by_name("page", "page_ns__page_id", "page_namespace", "page_id")); + page_conn.Meta_idx_create(Dbmeta_idx_itm.new_normal_by_tbl("page", "page_ns__page_id", "page_namespace", "page_id")); Srch_db_mgr.Optimize_unsafe_(word_conn, Bool_.Y); word_conn.Meta_tbl_remake(Dbmeta_tbl_itm.New("search_link_temp", Dbmeta_fld_itm.new_int("word_id"), Dbmeta_fld_itm.new_int("page_id"), Dbmeta_fld_itm.new_int("page_namespace"))); attach_mgr.Conn_main_(word_conn).Conn_others_(new Db_attach_itm("page_db", page_conn)); @@ -98,7 +98,7 @@ class Srch_temp_tbl_wkr implements Srch_text_parser_wkr { )); word_conn.Meta_idx_create(Dbmeta_idx_itm.new_normal_by_name("search_link_temp", "main", "page_namespace", "word_id", "page_id")); Srch_db_mgr.Optimize_unsafe_(word_conn, Bool_.N); - page_conn.Meta_idx_delete("page__page_ns__page_id"); + page_conn.Meta_idx_delete("page", "page_ns__page_id"); int len = search_db_mgr.Tbl__link__len(); for (int i = 0; i < len; ++i) { diff --git a/400_xowa/src/gplx/xowa/addons/wikis/searchs/specials/Srch_special_page.java b/400_xowa/src/gplx/xowa/addons/wikis/searchs/specials/Srch_special_page.java index f7c7553a4..86aa6a1a6 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/searchs/specials/Srch_special_page.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/searchs/specials/Srch_special_page.java @@ -86,7 +86,7 @@ public class Srch_special_page implements Xow_special_page, Gfo_invk, Gfo_evt_it page.Root().Data_htm_(search_page.Root().Data_htm()); Xoa_url redirect_url = Xoa_url.New(wiki, search_ttl); page.Ttl_(search_ttl).Url_(redirect_url); - page.Redirect().Itms__add__special(redirect_url, search_ttl); + page.Redirect().Itms__add__article(redirect_url, search_ttl, null); } } private void Multi_wikis_changed() { diff --git a/400_xowa/src/gplx/xowa/apps/boots/Xoa_boot_mgr.java b/400_xowa/src/gplx/xowa/apps/boots/Xoa_boot_mgr.java index 24111b4d0..d377412db 100644 --- a/400_xowa/src/gplx/xowa/apps/boots/Xoa_boot_mgr.java +++ b/400_xowa/src/gplx/xowa/apps/boots/Xoa_boot_mgr.java @@ -108,7 +108,7 @@ public class Xoa_boot_mgr { if (app_type_is_gui) app.Gui_mgr().Run(splash_win); else // teardown app, else lua will keep process running - gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(); + gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(app); } } catch (Exception e) {usr_dlg.Warn_many("", "", "app launch failed: ~{0}", Err_.Message_gplx_full(e));} diff --git a/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_data_tbl.java b/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_data_tbl.java deleted file mode 100644 index 663897a1a..000000000 --- a/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_data_tbl.java +++ /dev/null @@ -1,50 +0,0 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012 gnosygnu@gmail.com - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ -package gplx.xowa.apps.cfgs.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.cfgs.*; -import gplx.dbs.*; -public class Xocfg_data_tbl implements Rls_able { - private final String tbl_name; public final Dbmeta_fld_list flds = new Dbmeta_fld_list(); - private final String fld_key, fld_usr, fld_ctx, fld_val; - private final Db_conn conn; - public Xocfg_data_tbl(Db_conn conn) { - this.conn = conn; - tbl_name = Tbl_name; - fld_key = flds.Add_str_pkey ("cfg_key", 1024); // EX: "xowa.net.web_enabled" - fld_usr = flds.Add_str ("cfg_usr", 1024); // EX: "xowa_user" - fld_ctx = flds.Add_str ("cfg_ctx", 1024); // EX: "app" - fld_val = flds.Add_str ("cfg_val", 4096); // EX: "y" - } - public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));} - public void Insert(String key, String usr, String ctx, String val) { - Db_stmt stmt_insert = conn.Stmt_insert(tbl_name, flds); - stmt_insert.Clear().Val_str(fld_key, key).Val_str(fld_usr, usr).Val_str(fld_ctx, ctx).Val_str(fld_val, val) - .Exec_insert(); - } - public Xocfg_data_itm Select(String key, String usr, String ctx) { - Db_stmt stmt_select = conn.Stmt_select(tbl_name, flds, fld_key, fld_usr, fld_ctx); - Db_rdr rdr = stmt_select.Clear().Crt_str(fld_key, key).Crt_str(fld_usr, usr).Crt_str(fld_ctx, ctx).Exec_select__rls_auto(); - try { - if (rdr.Move_next()) - return new Xocfg_data_itm(key, usr, ctx, rdr.Read_str(fld_val)); - else - return null; - } finally {rdr.Rls();} - } - public void Rls() {conn.Rls_conn();} - public static final String Tbl_name = "cfg_data"; -} diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_dump_mgr_base.java b/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_dump_mgr_base.java index e14326e98..cf376099d 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_dump_mgr_base.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_dump_mgr_base.java @@ -145,7 +145,7 @@ public abstract class Xob_dump_mgr_base extends Xob_itm_basic_base implements Xo byte[] page_src = page.Text(); if (page_src != null) // some pages have no text; ignore them else null ref; PAGE: it.d:miercuri DATE:2015-12-05 Exec_pg_itm_hook(ns_ord, ns, page, page_src); - ctx.App().Utl__bfr_mkr().Clear_fail_check(); // make sure all bfrs are released + ctx.Wiki().Utl__bfr_mkr().Clear_fail_check(); // make sure all bfrs are released if (ctx.Wiki().Cache_mgr().Tmpl_result_cache().Count() > 50000) ctx.Wiki().Cache_mgr().Tmpl_result_cache().Clear(); ++exec_count; @@ -159,7 +159,7 @@ public abstract class Xob_dump_mgr_base extends Xob_itm_basic_base implements Xo } catch (Exception exc) { bldr.Usr_dlg().Warn_many("", "", "parse failed: wiki=~{0} ttl=~{1} err=~{2}", wiki.Domain_str(), page.Ttl_full_db(), Err_.Message_gplx_log(exc)); - ctx.App().Utl__bfr_mkr().Clear(); + ctx.Wiki().Utl__bfr_mkr().Clear(); this.Free(); } } diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_categorylinks_base.java b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_categorylinks_base.java index 8f61cde43..6ef6b965e 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_categorylinks_base.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_categorylinks_base.java @@ -69,6 +69,7 @@ public abstract class Xob_categorylinks_base extends Xob_sql_dump_base implement @Override public void Cmd_end() { Xobdc_merger.Basic(bldr.Usr_dlg(), dump_url_gen, temp_dir.GenSubDir("sort"), sort_mem_len, Xoctg_link_sql_sorter.Instance, Io_line_rdr_key_gen_.noop, Make_sort_cmd(sql_parser)); wiki.Html_mgr().Importing_ctgs_(Bool_.N); + gplx.xowa.bldrs.wkrs.Xob_io_utl_.Delete_sql_files(wiki.Fsys_mgr().Root_dir(), this.Sql_file_name()); } private static final byte[] Fld_cl_from = Bry_.new_a7("cl_from"), Fld_cl_to = Bry_.new_a7("cl_to"), Fld_cl_timestamp = Bry_.new_a7("cl_timestamp"), Fld_cl_collation = Bry_.new_a7("cl_collation"), Fld_cl_sortkey = Bry_.new_a7("cl_sortkey"), Fld_cl_type = Bry_.new_a7("cl_type"); private static final byte[] Collation_uca = Bry_.new_a7("uca"), Sortkey_space = new byte[] {Byte_ascii.Space}; diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_ctg_v1_base.java b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_ctg_v1_base.java index 3a451f409..312887bb2 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_ctg_v1_base.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_ctg_v1_base.java @@ -29,7 +29,7 @@ public abstract class Xob_ctg_v1_base extends Xob_itm_dump_base implements Xobd_ public Ordered_hash Wkr_hooks() {return wkr_hooks;} private Ordered_hash wkr_hooks = Ordered_hash_.New_bry(); public void Wkr_bgn(Xob_bldr bldr) { this.Init_dump(this.Wkr_key(), wiki.Tdb_fsys_mgr().Site_dir().GenSubDir(Xotdb_dir_info_.Name_category)); - Bry_bfr tmp_bfr = bldr.App().Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512(); Xol_lang_itm lang = wiki.Lang(); wkr_hooks_add(tmp_bfr, lang.Ns_names()); wkr_hooks_add(tmp_bfr, lang.Ns_aliases()); diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_ctg_v1_sql.java b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_ctg_v1_sql.java index 30022fe7f..e66b46b19 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_ctg_v1_sql.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_ctg_v1_sql.java @@ -27,7 +27,7 @@ class Xob_ctg_v1_sql_make implements Io_make_cmd { private Gfo_fld_rdr fld_rdr = Gfo_fld_rdr.xowa_(); private Xob_tmp_wtr sql_wtr; private Gfo_usr_dlg usr_dlg; private boolean is_first = true; private byte[] prv_ctg_name = Bry_.Empty; private int prv_page_id = 0; private Xowe_wiki wiki; private Xodb_mgr_sql db_mgr; private int page_count = 0; private int progress_interval = 10000; - private final Bry_fmtr fmtr = Bry_fmtr.new_("(~{page_id},'~{cat_name}','','','','','~{cat_type}')\n", "page_id", "cat_name", "cat_type"); + private final Bry_fmtr fmtr = Bry_fmtr.new_("(~{page_id},'~{cat_name}','','','','','~{cat_type}')\n", "page_id", "cat_name", "cat_type"); public Xob_ctg_v1_sql_make(Xowe_wiki wiki) {this.wiki = wiki; db_mgr = wiki.Db_mgr_as_sql();} public Io_sort_cmd Make_dir_(Io_url v) {return this;} // ignore public void Sort_bgn() { @@ -57,10 +57,10 @@ class Xob_ctg_v1_sql_make implements Io_make_cmd { sql_wtr.Flush(usr_dlg); db_mgr.Category_version_update(true); } - private static final byte[] Sql_hdr = Bry_.new_a7("INSERT INTO 'categorylinks' VALUES"); - public static final String Url_sql = "xowa_categorylinks.sql"; + private static final byte[] Sql_hdr = Bry_.new_a7("INSERT INTO 'categorylinks' VALUES"); + public static final String Url_sql = "xowa_categorylinks.sql"; private static byte[] Escape_for_sql(Xowe_wiki wiki, byte[] bry) { - Bry_bfr bfr = wiki.Appe().Utl__bfr_mkr().Get_b512(); + Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512(); int len = bry.length; boolean dirty = false; for (int i = 0; i < len; i++) { diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xoctg_hiddencat_parser_sql.java b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xoctg_hiddencat_parser_sql.java index 9537047c7..c5d2aa730 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xoctg_hiddencat_parser_sql.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xoctg_hiddencat_parser_sql.java @@ -38,12 +38,10 @@ public class Xoctg_hiddencat_parser_sql extends Xoctg_hiddencat_parser_base { tbl.Update_end(); if (!Env_.Mode_testing()) // NOTE: do not delete when testing Io_mgr.Instance.DeleteDirDeep(wiki.Fsys_mgr().Tmp_dir()); // delete /wiki/wiki_name/tmp - Io_url[] sql_files = Io_mgr.Instance.QueryDir_args(wiki.Fsys_mgr().Root_dir()).FilPath_("*.sql.gz").ExecAsUrlAry(); - int len = sql_files.length; - for (int i = 0; i < len; i++) { - Io_url sql_file = sql_files[i]; - Io_mgr.Instance.DeleteFil(sql_file); - } - Io_mgr.Instance.DeleteFil_args(wiki.Fsys_mgr().Root_dir().GenSubFil("xowa_categorylinks.sql")).MissingFails_off().Exec(); + + // cleanup; delete files; + Io_url wiki_root_dir = wiki.Fsys_mgr().Root_dir(); + gplx.xowa.bldrs.wkrs.Xob_io_utl_.Delete_sql_files(wiki_root_dir, this.Sql_file_name()); + Io_mgr.Instance.DeleteFil_args(wiki_root_dir.GenSubFil("xowa_categorylinks.sql")).MissingFails_off().Exec(); } } diff --git a/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_io_utl_.java b/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_io_utl_.java new file mode 100644 index 000000000..66532c301 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_io_utl_.java @@ -0,0 +1,60 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.wkrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +public class Xob_io_utl_ { + public static void Delete_sql_files(Io_url wiki_dir, String sql_file_name) { + Delete_by_wildcard(wiki_dir, sql_file_name + ".sql", ".gz", ".sql"); + } + public static void Delete_by_wildcard(Io_url dir, String name_pattern, String... ext_ary) { + List_adp list = Find_by_wildcard(Io_mgr.Instance.QueryDir_args(dir).ExecAsUrlAry(), name_pattern, ext_ary); + int len = list.Len(); + for (int i = 0; i < len; ++i) { + Io_url url = (Io_url)list.Get_at(i); + Io_mgr.Instance.DeleteFil(url); + } + } + public static Io_url Find_nth_by_wildcard_or_null(Io_url dir, String name_pattern, String... ext_ary) { + return Find_nth_by_wildcard_or_null(Io_mgr.Instance.QueryDir_args(dir).ExecAsUrlAry(), name_pattern, ext_ary); + } + public static Io_url Find_nth_by_wildcard_or_null(Io_url[] fil_ary, String name_pattern, String... ext_ary) { + List_adp list = Find_by_wildcard(fil_ary, name_pattern, ext_ary); + int list_len = list.Len(); + return list_len == 0 ? null : (Io_url)list.Get_at(list_len - 1); + } + public static List_adp Find_by_wildcard(Io_url[] fil_ary, String name_pattern, String... ext_ary) { + List_adp rv = List_adp_.New(); + + // create ext_hash + Ordered_hash ext_hash = Ordered_hash_.New(); + for (String ext : ext_ary) + ext_hash.Add(ext, ext); + + // iterate fil_ary + for (Io_url fil : fil_ary) { + // file matches pattern + if ( name_pattern == Pattern__wilcard // empty String means match anything + || String_.Has(fil.NameAndExt(), name_pattern)) { // name has name_pattern; EX: "enwiki-latest-pages-articles-current.xml" and "pagelinks" + if ( ext_hash.Len() == 0 // empty hash means match any ext + || ext_hash.Has(fil.Ext())) // ext exists in hash + rv.Add(fil); + } + } + return rv; + } + public static final String Pattern__wilcard = String_.Empty; +} diff --git a/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_io_utl__tst.java b/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_io_utl__tst.java new file mode 100644 index 000000000..cef84b418 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_io_utl__tst.java @@ -0,0 +1,43 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.wkrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import org.junit.*; import gplx.core.tests.*; +public class Xob_io_utl__tst { + private final Xob_io_utl__fxt fxt = new Xob_io_utl__fxt(); + @Test public void Basic() { + fxt.Test__match(String_.Ary("a.txt", "b.txt", "c.txt"), "b", String_.Ary(".txt"), "b.txt"); + } + @Test public void Include__ext() {// PURPOSE: handle calls like "a.sql", ".sql", ".gz" + fxt.Test__match(String_.Ary("a.txt", "b.txt", "c.txt"), "b.txt", String_.Ary(".txt"), "b.txt"); + } + @Test public void Dupe__pick_last() { + fxt.Test__match(String_.Ary("b0.txt", "b1.txt", "b2.txt"), "b", String_.Ary(".txt"), "b2.txt"); + } + @Test public void Ext() { + fxt.Test__match(String_.Ary("b.txt", "b.png", "b.xml"), "b", String_.Ary(".xml", ".bz2"), "b.xml"); + } + @Test public void Ext__dupes() { + fxt.Test__match(String_.Ary("b.txt", "b.png", "b.xml"), "b", String_.Ary(".txt", ".xml"), "b.xml"); + } +} +class Xob_io_utl__fxt { + public void Test__match(String[] path_ary, String name_pattern, String[] ext_ary, String expd) { + Io_url actl = Xob_io_utl_.Find_nth_by_wildcard_or_null(Io_url_.Ary(path_ary), name_pattern, ext_ary); + Gftest.Eq__str(expd, actl == null ? "<>" : actl.Raw()); + } +} \ No newline at end of file diff --git a/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_sql_dump_base.java b/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_sql_dump_base.java index 5159f53f5..eb1a0591e 100644 --- a/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_sql_dump_base.java +++ b/400_xowa/src/gplx/xowa/bldrs/wkrs/Xob_sql_dump_base.java @@ -29,7 +29,7 @@ public abstract class Xob_sql_dump_base extends Xob_itm_dump_base implements Xob this.Init_dump(this.Cmd_key()); make_url_gen = Io_url_gen_.dir_(temp_dir.GenSubDir("make")); if (src_fil == null) { - src_fil = Xotdb_fsys_mgr.Find_file_or_null(wiki.Fsys_mgr().Root_dir(), "*" + Sql_file_name() + "*", ".gz", ".sql"); + src_fil = Xob_io_utl_.Find_nth_by_wildcard_or_null(wiki.Fsys_mgr().Root_dir(), Sql_file_name() + ".sql", ".gz", ".sql"); if (src_fil == null) { String msg = String_.Format(".sql file not found in dir.\nPlease download the file for your wiki from dumps.wikimedia.org.\nfile={0} dir={1}", Sql_file_name(), wiki.Fsys_mgr().Root_dir()); app.Usr_dlg().Warn_many("", "", msg); diff --git a/400_xowa/src/gplx/xowa/bldrs/xmls/Xob_import_cfg.java b/400_xowa/src/gplx/xowa/bldrs/xmls/Xob_import_cfg.java index e13cb3f09..9cc98db42 100644 --- a/400_xowa/src/gplx/xowa/bldrs/xmls/Xob_import_cfg.java +++ b/400_xowa/src/gplx/xowa/bldrs/xmls/Xob_import_cfg.java @@ -18,6 +18,7 @@ along with this program. If not, see . package gplx.xowa.bldrs.xmls; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.core.ios.*; import gplx.core.ios.streams.*; import gplx.core.envs.*; import gplx.xowa.wikis.ctgs.*; import gplx.xowa.wikis.tdbs.*; +import gplx.xowa.bldrs.wkrs.*; public class Xob_import_cfg { public Xob_import_cfg(Xowe_wiki wiki) {this.wiki = wiki;} private Xowe_wiki wiki; private boolean src_fil_is_bz2 = true; public byte Category_version() {return category_version;} public Xob_import_cfg Category_version_(byte v) {category_version = v; return this;} private byte category_version = Xoa_ctg_mgr.Version_1; @@ -34,7 +35,8 @@ public class Xob_import_cfg { } public Io_stream_rdr Src_rdr() { if (src_fil_xml == null && src_fil_bz2 == null) { // will usually be null; non-null when user specifies src through command-line - Io_url url = Xotdb_fsys_mgr.Find_file_or_fail(wiki.Fsys_mgr().Root_dir(), "*", ".xml", ".bz2"); + Io_url url = Xob_io_utl_.Find_nth_by_wildcard_or_null(wiki.Fsys_mgr().Root_dir(), Xob_io_utl_.Pattern__wilcard, ".xml", ".bz2"); + if (url == null) throw Err_.new_wo_type("could not find any .xml or .bz2 file", "dir", wiki.Fsys_mgr().Root_dir().Raw()); if (String_.Eq(url.Ext(), ".xml")) Src_fil_xml_(url); else Src_fil_bz2_(url); } diff --git a/400_xowa/src/gplx/xowa/drds/files/Xod_fsys_mgr.java b/400_xowa/src/gplx/xowa/drds/files/Xod_fsys_mgr.java index 105139dcb..3d303e5b3 100644 --- a/400_xowa/src/gplx/xowa/drds/files/Xod_fsys_mgr.java +++ b/400_xowa/src/gplx/xowa/drds/files/Xod_fsys_mgr.java @@ -24,7 +24,7 @@ public class Xod_fsys_mgr { this.app_root_dir = usr_data_dir.GenSubDir_nest("files", "xowa"); String sdcard_rw = activity.Fsys__sdcard_rw_or_null(); if (sdcard_rw != null) { - app_root_dir = Io_url_.lnx_dir_(sdcard_rw + "/files/xowa/"); + app_root_dir = Io_url_.lnx_dir_(sdcard_rw + "files/xowa/"); } log.Info("fsys_mgr:root_dir", "root", app_root_dir.Xto_api()); } diff --git a/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm.java b/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm.java index 183655348..fa193ece3 100644 --- a/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm.java +++ b/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm.java @@ -107,10 +107,19 @@ public class Xog_tab_itm implements Gfo_invk { public void Show_url_bgn(Xoa_url url) { this.tab_is_loading = true; Xoae_app app = win.App(); Gfo_usr_dlg usr_dlg = app.Usr_dlg(); + + // get new_tab_name + Xoa_ttl ttl = Xoa_ttl.Parse(wiki, url.Page_bry()); + if (ttl == null) {usr_dlg.Prog_one("", "", "title is invalid: ~{0}", String_.new_u8(url.Raw())); return;} + String new_tab_name = String_.new_u8(ttl.Full_txt_w_ttl_case()); + + // if clicking on anchor, just scroll; do not load page if ( url.Anch_str() != null // url has anchor && url.Eq_page(page.Url()) // url has same page_name as existing page - && url.Qargs_ary().length == 0) { // url has no args; needed for Category:A?from=b#mw-pages - html_itm.Scroll_page_by_id_gui(url.Anch_str()); // skip page_load and jump to anchor + && url.Qargs_ary().length == 0 // url has no args; needed for Category:A?from=b#mw-pages + && String_.Eq(new_tab_name, tab_data.Name()) // NOTE: name will be null / empty when starting app and last session had page with #anchor; EX:Main_Page#Links; DATE:2016-07-21 + ) { + html_itm.Scroll_page_by_id_gui(url.Anch_str()); return; } if (win.Page__async__working(url)) return; @@ -120,9 +129,7 @@ public class Xog_tab_itm implements Gfo_invk { this.wiki = (Xowe_wiki)app.Wiki_mgr().Get_by_or_make_init_y(url.Wiki_bry()); // NOTE: must update wiki variable; DATE:????-??-??; NOTE: must load wiki; DATE:2015-07-22 if (url.Page_is_main()) url.Page_bry_(wiki.Props().Main_page()); if (url.Vnt_bry() != null) Cur_vnt_(wiki, url.Vnt_bry()); - Xoa_ttl ttl = Xoa_ttl.Parse(wiki, url.Page_bry()); - if (ttl == null) {usr_dlg.Prog_one("", "", "title is invalid: ~{0}", String_.new_u8(url.Raw())); return;} - Tab_name_(String_.new_u8(ttl.Full_txt_w_ttl_case())); + Tab_name_(new_tab_name); usr_dlg.Prog_one("", "", "loading: ~{0}", String_.new_u8(ttl.Raw())); if (app.Api_root().Html().Modules().Popups().Enabled()) this.Html_box().Html_js_eval_script("if (window.xowa_popups_hide_all != null) window.xowa_popups_hide_all();"); // should be more configurable; DATE:2014-07-09 diff --git a/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm_edit_mgr.java b/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm_edit_mgr.java index 9269c8862..9c976d6eb 100644 --- a/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm_edit_mgr.java +++ b/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm_edit_mgr.java @@ -107,7 +107,7 @@ public class Xog_tab_itm_edit_mgr { byte[] data = tab.Html_itm().Get_elem_value_for_edit_box_as_bry(); new_page.Db().Text().Text_bry_(data); wiki.Parser_mgr().Parse(new_page, true); - Bry_bfr bfr = win.App().Utl__bfr_mkr().Get_m001(); + Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_m001(); bfr.Add(new_page.Root().Root_src()); wiki.Parser_mgr().Ctx().Defn_trace().Print(data, bfr); new_page.Db().Text().Text_bry_(bfr.To_bry_and_rls()); diff --git a/400_xowa/src/gplx/xowa/htmls/Xoh_page.java b/400_xowa/src/gplx/xowa/htmls/Xoh_page.java index 1175dd4c8..80de7a935 100644 --- a/400_xowa/src/gplx/xowa/htmls/Xoh_page.java +++ b/400_xowa/src/gplx/xowa/htmls/Xoh_page.java @@ -26,7 +26,7 @@ public class Xoh_page implements Xoa_page { public Xoa_url Url() {return page_url;} private Xoa_url page_url; public Xoa_ttl Ttl() {return page_ttl;} private Xoa_ttl page_ttl; public Xopg_db_data Db() {return db;} private final Xopg_db_data db = new Xopg_db_data(); - public Xopg_redirect_data Redirect() {return redirect;} private final Xopg_redirect_data redirect = new Xopg_redirect_data(); + public Xopg_redirect_mgr Redirect() {return redirect;} private final Xopg_redirect_mgr redirect = new Xopg_redirect_mgr(); public Xopg_html_data Html_data() {return html;} private final Xopg_html_data html = new Xopg_html_data(); public Xopg_hdump_data Hdump_mgr() {return hdump;} private final Xopg_hdump_data hdump = new Xopg_hdump_data(); diff --git a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java index f54bbaa97..5127458c7 100644 --- a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java +++ b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java @@ -99,8 +99,8 @@ public class Xoh_page_wtr_wkr { , mgr.Css_common_bry(), mgr.Css_wiki_bry(), page.Html_data().Head_mgr().Init(app, wiki, page).Init_dflts() , page.Lang().Dir_ltr_bry(), page.Html_data().Indicators(), page_content_sub, wiki.Html_mgr().Portal_mgr().Div_jump_to(), wiki.Xtn_mgr().Xtn_pgbnr().Write_html(page, ctx, hctx), page_body_class, html_content_editable , page_data, wdata_lang_wtr - , portal_mgr.Div_personal_bry(), portal_mgr.Div_ns_bry(app.Utl__bfr_mkr(), page_ttl, wiki.Ns_mgr()), portal_mgr.Div_view_bry(app.Utl__bfr_mkr(), html_gen_tid, page.Html_data().Xtn_search_text()) - , portal_mgr.Div_logo_bry(), portal_mgr.Div_home_bry(), new Xopg_xtn_skin_fmtr_arg(page, Xopg_xtn_skin_itm_tid.Tid_sidebar), portal_mgr.Div_wikis_bry(app.Utl__bfr_mkr()), portal_mgr.Sidebar_mgr().Html_bry() + , portal_mgr.Div_personal_bry(), portal_mgr.Div_ns_bry(wiki.Utl__bfr_mkr(), page_ttl, wiki.Ns_mgr()), portal_mgr.Div_view_bry(wiki.Utl__bfr_mkr(), html_gen_tid, page.Html_data().Xtn_search_text()) + , portal_mgr.Div_logo_bry(), portal_mgr.Div_home_bry(), new Xopg_xtn_skin_fmtr_arg(page, Xopg_xtn_skin_itm_tid.Tid_sidebar), portal_mgr.Div_wikis_bry(wiki.Utl__bfr_mkr()), portal_mgr.Sidebar_mgr().Html_bry() , mgr.Edit_rename_div_bry(page_ttl), page.Html_data().Edit_preview_w_dbg(), js_edit_toolbar_bry ); Xoh_page_wtr_wkr_.Bld_head_end(bfr, tmp_bfr, page); // add after @@ -152,7 +152,7 @@ public class Xoh_page_wtr_wkr { // if [[File]], add boilerplate header; note that html is XOWA-generated so does not need to be tidied if (ns_id == Xow_ns_.Tid__file) app.Ns_file_page_mgr().Bld_html(wiki, ctx, page, bfr, page.Ttl(), wiki.Cfg_file_page(), page.File_queue()); // get separate bfr; note that bfr already has and written to it, so this can't be passed to tidy; DATE:2014-06-11 - Bry_bfr tidy_bfr = app.Utl__bfr_mkr().Get_m001(); + Bry_bfr tidy_bfr = wiki.Utl__bfr_mkr().Get_m001(); // write wikitext if (page.Html_data().Skip_parse()) { tidy_bfr.Add(page.Html_data().Custom_body()); diff --git a/400_xowa/src/gplx/xowa/htmls/heads/Xoh_head_itm__globals.java b/400_xowa/src/gplx/xowa/htmls/heads/Xoh_head_itm__globals.java index 2ffcb41c9..171ebad74 100644 --- a/400_xowa/src/gplx/xowa/htmls/heads/Xoh_head_itm__globals.java +++ b/400_xowa/src/gplx/xowa/htmls/heads/Xoh_head_itm__globals.java @@ -53,7 +53,7 @@ public class Xoh_head_itm__globals extends Xoh_head_itm__base { wtr.Write_js_global_ini_atr_msg(wiki, Key_sort_ascending); wtr.Write_js_global_ini_atr_msg(wiki, Key_sort_descending); Xol_lang_itm lang = wiki.Lang(); Xow_msg_mgr msg_mgr = wiki.Msg_mgr(); - Bry_bfr tmp_bfr = app.Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512(); tmp_wtr.Init(tmp_bfr); byte[] months_long = Html_js_table_months(tmp_wtr, msg_mgr, Xol_msg_itm_.Id_dte_month_name_january, Xol_msg_itm_.Id_dte_month_name_december); byte[] months_short = Html_js_table_months(tmp_wtr, msg_mgr, Xol_msg_itm_.Id_dte_month_abrv_jan, Xol_msg_itm_.Id_dte_month_abrv_dec); diff --git a/400_xowa/src/gplx/xowa/langs/funcs/Xol_func_regy.java b/400_xowa/src/gplx/xowa/langs/funcs/Xol_func_regy.java index 7d7242dc5..fe77decd0 100644 --- a/400_xowa/src/gplx/xowa/langs/funcs/Xol_func_regy.java +++ b/400_xowa/src/gplx/xowa/langs/funcs/Xol_func_regy.java @@ -51,14 +51,12 @@ public class Xol_func_regy { } } private void Add(byte[] ary, boolean case_match, Xot_defn func) { -// synchronized (thread_lock) { // LOCK:DELETE; DATE:2016-07-06 - if (case_match) - cs_trie.Add_obj(ary, func); - else { - byte[] lower_ary = lang.Case_mgr().Case_build_lower(ary, 0, ary.length); - ci_trie.Add_obj(lower_ary, func); - } -// } + if (case_match) + cs_trie.Add_obj(ary, func); + else { + byte[] lower_ary = lang.Case_mgr().Case_build_lower(ary, 0, ary.length); + ci_trie.Add_obj(lower_ary, func); + } } public void Find_defn(Xol_func_itm rv, byte[] src, int txt_bgn, int txt_end) { rv.Clear(); diff --git a/400_xowa/src/gplx/xowa/parsers/Xop_ctx.java b/400_xowa/src/gplx/xowa/parsers/Xop_ctx.java index 5c7578ea2..714ab2bb1 100644 --- a/400_xowa/src/gplx/xowa/parsers/Xop_ctx.java +++ b/400_xowa/src/gplx/xowa/parsers/Xop_ctx.java @@ -52,6 +52,7 @@ public class Xop_ctx { public Xot_invk_wkr Invk() {return invk;} private final Xot_invk_wkr invk = new Xot_invk_wkr(); public Xop_curly_wkr Curly() {return curly;} private final Xop_curly_wkr curly = new Xop_curly_wkr(); public Xop_xnde_tag_regy Xnde_tag_regy() {return xnde_tag_regy;} private final Xop_xnde_tag_regy xnde_tag_regy; // PERF:demeter + public Xop_tmp_mgr Tmp_mgr() {return tmp_mgr;} private final Xop_tmp_mgr tmp_mgr = new Xop_tmp_mgr(); public byte Xnde_names_tid() {return xnde_names_tid;} public Xop_ctx Xnde_names_tid_(byte v) {xnde_names_tid = v; return this;} private byte xnde_names_tid = Xop_parser_tid_.Tid__null; public byte Parse_tid() {return parse_tid;} public Xop_ctx Parse_tid_(byte v) {parse_tid = v; xnde_names_tid = v; return this;} private byte parse_tid = Xop_parser_tid_.Tid__null; @@ -84,7 +85,6 @@ public class Xop_ctx { cur_page.Clear(clear_scrib); stack = Xop_tkn_itm_.Ary_empty; stack_len = stack_max = 0; - app.Wiki_mgr().Wdata_mgr().Clear(); if (lst_section_mgr != null) lst_section_mgr.Clear(); if (lst_page_regy != null) lst_page_regy.Clear(); tmpl_output = null; diff --git a/400_xowa/src/gplx/xowa/parsers/Xop_tmp_mgr.java b/400_xowa/src/gplx/xowa/parsers/Xop_tmp_mgr.java new file mode 100644 index 000000000..dedde0de1 --- /dev/null +++ b/400_xowa/src/gplx/xowa/parsers/Xop_tmp_mgr.java @@ -0,0 +1,28 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*; +import gplx.core.primitives.*; +import gplx.xowa.files.*; +import gplx.xowa.xtns.pfuncs.exprs.*; import gplx.xowa.xtns.math.*; +public class Xop_tmp_mgr { + public Xof_math_itm Math_itm() {return math_itm;} private final Xof_math_itm math_itm = new Xof_math_itm(); + public Xof_xfer_itm Xfer_itm() {return xfer_itm;} private final Xof_xfer_itm xfer_itm = new Xof_xfer_itm(); + public Number_parser Pfunc_num_parser_0() {return num_parser_0;} private final Number_parser num_parser_0 = new Number_parser().Hex_enabled_(true); + public Number_parser Pfunc_num_parser_1() {return num_parser_1;} private final Number_parser num_parser_1 = new Number_parser().Hex_enabled_(true); + public Pfunc_expr_shunter Expr_shunter() {return expr_shunter;} private final Pfunc_expr_shunter expr_shunter = new Pfunc_expr_shunter(); +} diff --git a/400_xowa/src/gplx/xowa/parsers/Xow_parser_mgr.java b/400_xowa/src/gplx/xowa/parsers/Xow_parser_mgr.java index 4764908a7..820793edc 100644 --- a/400_xowa/src/gplx/xowa/parsers/Xow_parser_mgr.java +++ b/400_xowa/src/gplx/xowa/parsers/Xow_parser_mgr.java @@ -16,9 +16,10 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*; +// using gplx.langs.jsons; import gplx.xowa.wikis.*; import gplx.core.envs.*; import gplx.xowa.files.*; -import gplx.xowa.xtns.pfuncs.ifs.*; import gplx.xowa.xtns.scribunto.*; +import gplx.xowa.xtns.pfuncs.ifs.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.pfuncs.times.*; public class Xow_parser_mgr { private final Xowe_wiki wiki; private final Xop_tkn_mkr tkn_mkr; private Xop_parser anchor_encode_parser; @@ -27,11 +28,14 @@ public class Xow_parser_mgr { this.ctx = Xop_ctx.New__top(wiki); this.parser = Xop_parser.new_wiki(wiki); } - public Xop_ctx Ctx() {return ctx;} private final Xop_ctx ctx; - public Xop_parser Main() {return parser;} private final Xop_parser parser; - public Scrib_core_mgr Scrib() {return scrib;} private final Scrib_core_mgr scrib = new Scrib_core_mgr(); - public Pfunc_ifexist_mgr Ifexist_mgr() {return ifexist_mgr;} private final Pfunc_ifexist_mgr ifexist_mgr = new Pfunc_ifexist_mgr(); - public Xof_url_bldr Url_bldr() {return url_bldr;} private final Xof_url_bldr url_bldr = Xof_url_bldr.new_v2(); + public Xop_ctx Ctx() {return ctx;} private final Xop_ctx ctx; + public Xop_parser Main() {return parser;} private final Xop_parser parser; + public Scrib_core_mgr Scrib() {return scrib;} private final Scrib_core_mgr scrib = new Scrib_core_mgr(); + public Pfunc_ifexist_mgr Ifexist_mgr() {return ifexist_mgr;} private final Pfunc_ifexist_mgr ifexist_mgr = new Pfunc_ifexist_mgr(); + public Xof_url_bldr Url_bldr() {return url_bldr;} private final Xof_url_bldr url_bldr = Xof_url_bldr.new_v2(); + public List_adp Time_parser_itms() {return time_parser_itms;} private final List_adp time_parser_itms = List_adp_.New(); + public Pft_func_formatdate_bldr Date_fmt_bldr() {return date_fmt_bldr;} private final Pft_func_formatdate_bldr date_fmt_bldr = new Pft_func_formatdate_bldr(); + // public Json_parser Wbase_jdoc_parser() {return wbase_jdoc_parser;} private final Json_parser wbase_jdoc_parser = new Json_parser(); public Xop_parser Anchor_encoder() { if (anchor_encode_parser == null) { anchor_encode_parser = Xop_parser.new_(wiki, wiki.Parser_mgr().Main().Tmpl_lxr_mgr(), Xop_lxr_mgr.new_anchor_encoder()); @@ -42,7 +46,7 @@ public class Xow_parser_mgr { } public void Parse(Xoae_page page, boolean clear) { // main parse method if (!Env_.Mode_testing()) wiki.Init_assert(); - scrib.Core_page_changed(page); // notify scribunto about page changed + scrib.When_page_changed(page); // notify scribunto about page changed ctx.Page_(page); Xop_root_tkn root = ctx.Tkn_mkr().Root(page.Db().Text().Text_bry()); if (clear) {page.Clear_all();} diff --git a/400_xowa/src/gplx/xowa/parsers/lnkes/Xop_lnke_wkr.java b/400_xowa/src/gplx/xowa/parsers/lnkes/Xop_lnke_wkr.java index b6dfa8b81..c8fbad6f2 100644 --- a/400_xowa/src/gplx/xowa/parsers/lnkes/Xop_lnke_wkr.java +++ b/400_xowa/src/gplx/xowa/parsers/lnkes/Xop_lnke_wkr.java @@ -287,7 +287,7 @@ public class Xop_lnke_wkr implements Xop_ctx_wkr { int lnke_bgn_pos = lhs_dlm_pos + 1; byte[] rhs_dlm_bry = Bry_quote; if (lhs_dlm_pos - proto_end_pos > 0) { - Bry_bfr bfr = ctx.App().Utl__bfr_mkr().Get_k004(); + Bry_bfr bfr = ctx.Wiki().Utl__bfr_mkr().Get_k004(); rhs_dlm_bry = bfr.Add(Bry_quote).Add_mid(src, proto_end_pos, lhs_dlm_pos).To_bry_and_clear(); bfr.Mkr_rls(); } diff --git a/400_xowa/src/gplx/xowa/parsers/lnkis/Xop_lnki_wkr_.java b/400_xowa/src/gplx/xowa/parsers/lnkis/Xop_lnki_wkr_.java index 3a5b4ea25..7cc0dbf97 100644 --- a/400_xowa/src/gplx/xowa/parsers/lnkis/Xop_lnki_wkr_.java +++ b/400_xowa/src/gplx/xowa/parsers/lnkis/Xop_lnki_wkr_.java @@ -41,14 +41,13 @@ public class Xop_lnki_wkr_ { return Parse_ttl(ctx, src, lnki, ttl_bgn, ttl_end); } public static boolean Parse_ttl(Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, int ttl_bgn, int ttl_end) { - Xoae_app app = ctx.App(); byte[] ttl_bry = Bry_.Mid(src, ttl_bgn, ttl_end); ttl_bry = gplx.langs.htmls.encoders.Gfo_url_encoder_.Http_url_ttl.Decode(ttl_bry); int ttl_bry_len = ttl_bry.length; Xoa_ttl page_ttl = ctx.Page().Ttl(); if (page_ttl.Ns().Subpages_enabled() && Pfunc_rel2abs.Rel2abs_ttl(ttl_bry, 0, ttl_bry_len)) { // Linker.php|normalizeSubpageLink - Bry_bfr tmp_bfr = app.Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512(); byte[] new_bry = Pfunc_rel2abs.Rel2abs(tmp_bfr, ttl_bry, page_ttl.Raw(), rel2abs_tid.Val_zero_()); lnki.Subpage_tid_(rel2abs_tid.Val()); lnki.Subpage_slash_at_end_(Bry_.Get_at_end(ttl_bry) == Byte_ascii.Slash); diff --git a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_defn_tmpl.java b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_defn_tmpl.java index 50eab6ace..1f32fbcf3 100644 --- a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_defn_tmpl.java +++ b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_defn_tmpl.java @@ -62,35 +62,33 @@ public class Xot_defn_tmpl implements Xot_defn { } public void Parse_tmpl(Xop_ctx ctx) {ctx.Wiki().Parser_mgr().Main().Parse_text_to_defn(this, ctx, ctx.Tkn_mkr(), ns, name, data_raw);} boolean onlyinclude_parsed = false; public boolean Tmpl_evaluate(Xop_ctx ctx, Xot_invk caller, Bry_bfr bfr) { -// synchronized (this) { // LOCK:DELETE; DATE:2016-07-06 - if (root == null) Parse_tmpl(ctx); - Xoae_page page = ctx.Page(); - if (!page.Tmpl_stack_add(full_name)) { - bfr.Add_str_a7(""); - Xoa_app_.Usr_dlg().Log_many("", "", "template loop detected: url=~{0} name=~{1}", ctx.Page().Url().To_str(), name); - return false; + if (root == null) Parse_tmpl(ctx); + Xoae_page page = ctx.Page(); + if (!page.Tmpl_stack_add(full_name)) { + bfr.Add_str_a7(""); + Xoa_app_.Usr_dlg().Log_many("", "", "template loop detected: url=~{0} name=~{1}", ctx.Page().Url().To_str(), name); + return false; + } + boolean rv = true; + if (onlyInclude_exists) { + Xowe_wiki wiki = ctx.Wiki(); + if (!onlyinclude_parsed) { + onlyinclude_parsed = true; + byte[] new_data = Extract_onlyinclude(data_raw, wiki.Utl__bfr_mkr()); + Xop_ctx new_ctx = Xop_ctx.New__sub(wiki, ctx, page); // COMMENT:changed from ctx.Page() to page; DATE:2016-07-11 + Xot_defn_tmpl tmpl = wiki.Parser_mgr().Main().Parse_text_to_defn_obj(new_ctx, new_ctx.Tkn_mkr(), wiki.Ns_mgr().Ns_template(), Bry_.Empty, new_data); + tmpl.Root().Tmpl_compile(new_ctx, new_data, Xot_compile_data.Null); + data_raw = new_data; + root = tmpl.Root(); } - boolean rv = true; - if (onlyInclude_exists) { - Xowe_wiki wiki = ctx.Wiki(); - if (!onlyinclude_parsed) { - onlyinclude_parsed = true; - byte[] new_data = Extract_onlyinclude(data_raw, wiki.Utl__bfr_mkr()); - Xop_ctx new_ctx = Xop_ctx.New__sub(wiki, ctx, page); // COMMENT:changed from ctx.Page() to page; DATE:2016-07-11 - Xot_defn_tmpl tmpl = wiki.Parser_mgr().Main().Parse_text_to_defn_obj(new_ctx, new_ctx.Tkn_mkr(), wiki.Ns_mgr().Ns_template(), Bry_.Empty, new_data); - tmpl.Root().Tmpl_compile(new_ctx, new_data, Xot_compile_data.Null); - data_raw = new_data; - root = tmpl.Root(); - } - } - int subs_len = root.Subs_len(); - for (int i = 0; i < subs_len; i++) { - boolean result = root.Subs_get(i).Tmpl_evaluate(ctx, data_raw, caller, bfr); - if (!result) rv = false; - } - page.Tmpl_stack_del(); - return rv; -// } + } + int subs_len = root.Subs_len(); + for (int i = 0; i < subs_len; i++) { + boolean result = root.Subs_get(i).Tmpl_evaluate(ctx, data_raw, caller, bfr); + if (!result) rv = false; + } + page.Tmpl_stack_del(); + return rv; } public Xot_defn Clone(int id, byte[] name) {throw Err_.new_unimplemented();} boolean onlyInclude_exists; diff --git a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_temp.java b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_temp.java index 296ea3c18..0b4e7d7a7 100644 --- a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_temp.java +++ b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_temp.java @@ -20,7 +20,7 @@ import gplx.core.primitives.*; import gplx.xowa.xtns.scribunto.*; public class Xot_invk_temp implements Xot_invk { private List_adp list = List_adp_.New(); - private Hash_adp_bry arg_key_hash; + private Hash_adp_bry arg_key_hash; private Hash_adp arg_idx_hash; private Int_obj_ref arg_idx_ref; Xot_invk_temp() {} public Xot_invk_temp(boolean root_frame) {this.root_frame = root_frame;} diff --git a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_tkn.java b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_tkn.java index 422a2150e..e0dbbdf77 100644 --- a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_tkn.java +++ b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_tkn.java @@ -233,7 +233,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk { } if (ignore_hash.Get_by_bry(name_ary) == null) { if (Pfunc_rel2abs.Rel2abs_ttl(name_ary, name_bgn, name_ary_len)) {// rel_path; EX: {{/../Peer page}}; DATE:2013-03-27 - Bry_bfr tmp_bfr = ctx.App().Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512(); name_ary = Pfunc_rel2abs.Rel2abs(tmp_bfr, Bry_.Mid(name_ary, name_bgn, name_ary_len), ctx.Page().Ttl().Raw()); tmp_bfr.Mkr_rls(); return SubEval(ctx, wiki, bfr, name_ary, caller, src); diff --git a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_tmpl_wtr.java b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_tmpl_wtr.java index ce37a6946..443107ae9 100644 --- a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_tmpl_wtr.java +++ b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_tmpl_wtr.java @@ -21,7 +21,7 @@ import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.miscs.*; public class Xot_tmpl_wtr { public byte[] Write_all(Xop_ctx ctx, Xop_root_tkn root, byte[] src) { // synchronized (this) { // THREAD:added synchronized after "failed to write tkn" DATE:2015-04-29 - Bry_bfr rslt_bfr = ctx.App().Utl__bfr_mkr().Get_m001(); + Bry_bfr rslt_bfr = ctx.Wiki().Utl__bfr_mkr().Get_m001(); ctx.Tmpl_output_(rslt_bfr); rslt_bfr.Reset_if_gt(Io_mgr.Len_mb); Write_tkn(ctx, src, src.length, rslt_bfr, root); @@ -68,7 +68,7 @@ public class Xot_tmpl_wtr { if (xnde.Tag_close_bgn() == Int_.Min_value) rslt_bfr.Add_mid(src, tkn.Src_bgn(), tkn.Src_end()); // write src from bgn/end else { // NOTE: if nowiki then "deactivate" all xndes by swapping out < for < nowiki_xnde_frag; DATE:2013-01-27 - Bry_bfr tmp_bfr = ctx.Wiki().Appe().Utl__bfr_mkr().Get_k004(); + Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_k004(); int nowiki_content_bgn = xnde.Tag_open_end(), nowiki_content_end = xnde.Tag_close_bgn(); boolean escaped = gplx.xowa.parsers.tmpls.Nowiki_escape_itm.Escape(tmp_bfr, src, nowiki_content_bgn, nowiki_content_end); rslt_bfr.Add_bfr_or_mid(escaped, tmp_bfr, src, nowiki_content_bgn, nowiki_content_end); diff --git a/400_xowa/src/gplx/xowa/parsers/utils/Xop_redirect_mgr.java b/400_xowa/src/gplx/xowa/parsers/utils/Xop_redirect_mgr.java index 87f3ea47b..6da6632c5 100644 --- a/400_xowa/src/gplx/xowa/parsers/utils/Xop_redirect_mgr.java +++ b/400_xowa/src/gplx/xowa/parsers/utils/Xop_redirect_mgr.java @@ -70,7 +70,7 @@ public class Xop_redirect_mgr { , Xop_tkn_.Lnki_end // "]]" ); } - public static byte[] Bld_redirect_msg(Xoae_app app, Xowe_wiki wiki, Xopg_redirect_data redirect_mgr) { + public static byte[] Bld_redirect_msg(Xoae_app app, Xowe_wiki wiki, Xopg_redirect_mgr redirect_mgr) { int len = redirect_mgr.Itms__len(); if (len == 0) return Bry_.Empty; Bry_bfr redirect_bfr = Xoa_app_.Utl__bfr_mkr().Get_b512(); boolean dirty = false; @@ -93,7 +93,7 @@ public class Xop_redirect_mgr { } if (!dirty) return Bry_.Empty; // ignore Special:Redirects else Special:Random will always show "redirected from"; DATE:2016-07-05 Xol_msg_itm msg_itm = wiki.Lang().Msg_mgr().Itm_by_id_or_null(Xol_msg_itm_.Id_redirectedfrom); - Bry_bfr fmt_bfr = app.Utl__bfr_mkr().Get_b512(); + Bry_bfr fmt_bfr = wiki.Utl__bfr_mkr().Get_b512(); app.Tmp_fmtr().Fmt_(msg_itm.Val()).Bld_bfr_one(fmt_bfr, redirect_bfr); redirect_bfr.Clear().Mkr_rls(); fmt_bfr.Mkr_rls(); return fmt_bfr.To_bry_and_clear(); diff --git a/400_xowa/src/gplx/xowa/parsers/utils/Xop_redirect_mgr_tst.java b/400_xowa/src/gplx/xowa/parsers/utils/Xop_redirect_mgr_tst.java index b156ab5e5..868aa0196 100644 --- a/400_xowa/src/gplx/xowa/parsers/utils/Xop_redirect_mgr_tst.java +++ b/400_xowa/src/gplx/xowa/parsers/utils/Xop_redirect_mgr_tst.java @@ -76,7 +76,7 @@ class Xop_redirect_mgr_fxt { Tfds.Eq(expd_str, String_.new_u8(actl_bry)); } public void Test__redirected_html(String page_str, String expd_str) { - gplx.xowa.wikis.pages.redirects.Xopg_redirect_data redirect_mgr = new gplx.xowa.wikis.pages.redirects.Xopg_redirect_data(); + gplx.xowa.wikis.pages.redirects.Xopg_redirect_mgr redirect_mgr = new gplx.xowa.wikis.pages.redirects.Xopg_redirect_mgr(); Xoa_ttl ttl = fxt.Wiki().Ttl_parse(Bry_.new_u8(page_str)); Xoa_url url = Xoa_url.New(fxt.Wiki(), ttl); redirect_mgr.Itms__add__article(url, ttl, Bry_.Empty); diff --git a/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_wkr_.java b/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_wkr_.java index a124119b8..367c8b8b3 100644 --- a/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_wkr_.java +++ b/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_wkr_.java @@ -22,7 +22,6 @@ class Xop_xnde_wkr_ { private static final Btrie_slim_mgr xtn_end_tag_trie = Btrie_slim_mgr.ci_a7(); // NOTE:ci.ascii:MW_const.en; listed XML node names are en private static final int Find_xtn_end__tid__bgn = 0, Find_xtn_end__tid__end = 1, Find_xtn_end__tid__xtag = 2; private static final Int_obj_ref Find_xtn_end__key__bgn = Int_obj_ref.New(Find_xtn_end__tid__bgn), Find_xtn_end__key__end = Int_obj_ref.New(Find_xtn_end__tid__end), Find_xtn_end__key__xtag = Int_obj_ref.New(Find_xtn_end__tid__xtag); - private static final Bry_bfr Find_xtag_end__bfr = Bry_bfr_.New_w_size(32); public static void AutoClose_handle_dangling_nde_in_caption(Xop_root_tkn root, Xop_tkn_itm owner) { int subs_bgn = -1, subs_len = owner.Subs_len(); for (int i = 0; i < subs_len; i++) { @@ -73,8 +72,10 @@ class Xop_xnde_wkr_ { public static int Find_xtag_end(Xop_ctx ctx, byte[] src, int pos, int src_end) { int xtag_bgn = pos + Pfunc_tag.Xtag_bgn_lhs.length; int tag_id = Bry_.To_int_or(src, xtag_bgn, xtag_bgn + Pfunc_tag.Id_len, -1); if (tag_id == -1) {Xoa_app_.Usr_dlg().Warn_many("", "", "parser.xtn: could not extract id from xtag_bgn: page=~{0}", ctx.Page().Url().To_str()); return Bry_find_.Not_found;} - Find_xtag_end__bfr.Add(Pfunc_tag.Xtag_end_lhs).Add_int_pad_bgn(Byte_ascii.Num_0, Pfunc_tag.Id_len, tag_id).Add(Pfunc_tag.Xtag_rhs); - byte[] tag_end = Find_xtag_end__bfr.To_bry_and_clear(); + Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b128(); + tmp_bfr.Add(Pfunc_tag.Xtag_end_lhs).Add_int_pad_bgn(Byte_ascii.Num_0, Pfunc_tag.Id_len, tag_id).Add(Pfunc_tag.Xtag_rhs); + byte[] tag_end = tmp_bfr.To_bry_and_clear(); + tmp_bfr.Mkr_rls(); int rv = Bry_find_.Find_fwd(src, tag_end, pos + Pfunc_tag.Xtag_rhs.length); if (rv == Bry_find_.Not_found) {ctx.App().Usr_dlg().Warn_many("", "", "parser.xtn: could not find xtag end: page=~{0}", ctx.Page().Url().To_str()); return Bry_find_.Not_found;} rv = Bry_find_.Find_bwd(src, Byte_ascii.Lt, rv - 1); if (rv == Bry_find_.Not_found) {ctx.App().Usr_dlg().Warn_many("", "", "parser.xtn: could not find <: page=~{0}", ctx.Page().Url().To_str()); return Bry_find_.Not_found;} return rv; diff --git a/400_xowa/src/gplx/xowa/specials/xowa/system_data/System_data_page.java b/400_xowa/src/gplx/xowa/specials/xowa/system_data/System_data_page.java index 0ddb667e1..666c592e9 100644 --- a/400_xowa/src/gplx/xowa/specials/xowa/system_data/System_data_page.java +++ b/400_xowa/src/gplx/xowa/specials/xowa/system_data/System_data_page.java @@ -28,9 +28,18 @@ public class System_data_page implements Xow_special_page { byte[] file_type = arg_hash.Get_val_bry_or(Arg_type, null); if (file_type == null) return; Byte_obj_val type_val = (Byte_obj_val)type_hash.Get_by_bry(file_type); if (type_val == null) return; Io_url file_url = Path_from_type(wiki, type_val.Val()); if (file_url == null) return; - Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001(); + + // get log text byte[] file_txt = Io_mgr.Instance.LoadFilBry(file_url); file_txt = gplx.langs.htmls.Gfh_utl.Escape_html_as_bry(file_txt, true, false, false, false, false); // escape < or "" in messages will cause pre to break + if (file_txt.length > Io_mgr.Len_mb) { + int file_txt_len = file_txt.length; + file_txt = Bry_.Add + ( Bry_.new_a7("*** truncated to 1 MB due to large file size: " + Int_.To_str(file_txt_len) + " ***\n\n") + , Bry_.Mid(file_txt, file_txt_len - Io_mgr.Len_mb, file_txt_len)); + } + + Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001(); fmtr_all.Bld_bfr_many(tmp_bfr, file_url.Raw(), file_txt); page.Db().Text().Text_bry_(tmp_bfr.To_bry_and_rls()); } diff --git a/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_meta_itm.java b/400_xowa/src/gplx/xowa/users/cfgs/Xocfg_meta_itm.java similarity index 89% rename from 400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_meta_itm.java rename to 400_xowa/src/gplx/xowa/users/cfgs/Xocfg_meta_itm.java index 37813eee9..dffc810f7 100644 --- a/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_meta_itm.java +++ b/400_xowa/src/gplx/xowa/users/cfgs/Xocfg_meta_itm.java @@ -15,7 +15,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package gplx.xowa.apps.cfgs.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.cfgs.*; +package gplx.xowa.users.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*; public class Xocfg_meta_itm { public Xocfg_meta_itm(String key, String type, String dflt, String version) { this.key = key; this.type = type; this.dflt = dflt; this.version = version; diff --git a/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_meta_tbl.java b/400_xowa/src/gplx/xowa/users/cfgs/Xocfg_meta_tbl.java similarity index 92% rename from 400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_meta_tbl.java rename to 400_xowa/src/gplx/xowa/users/cfgs/Xocfg_meta_tbl.java index 15bd2fc75..289a9d17b 100644 --- a/400_xowa/src/gplx/xowa/apps/cfgs/dbs/Xocfg_meta_tbl.java +++ b/400_xowa/src/gplx/xowa/users/cfgs/Xocfg_meta_tbl.java @@ -15,7 +15,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package gplx.xowa.apps.cfgs.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.cfgs.*; +package gplx.xowa.users.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*; import gplx.dbs.*; public class Xocfg_meta_tbl implements Rls_able { private final String tbl_name; public final Dbmeta_fld_list flds = new Dbmeta_fld_list(); diff --git a/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_itm.java b/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_itm.java new file mode 100644 index 000000000..e365b76f2 --- /dev/null +++ b/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_itm.java @@ -0,0 +1,30 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.users.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*; +public class Xou_cfg_itm { + public Xou_cfg_itm(int usr, String ctx, String key, String val) { + this.usr = usr; this.ctx = ctx; this.key = key; this.val = val; + this.uid = Xou_cfg_mgr.Bld_uid(usr, ctx, key); + } + public String Uid() {return uid;} private final String uid; + public int Usr() {return usr;} private final int usr; + public String Ctx() {return ctx;} private final String ctx; + public String Key() {return key;} private final String key; + public String Val() {return val;} private String val; + public void Val_(String v) {this.val = v;} +} diff --git a/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_mgr.java b/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_mgr.java new file mode 100644 index 000000000..5015cbe2b --- /dev/null +++ b/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_mgr.java @@ -0,0 +1,73 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.users.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*; +import gplx.dbs.*; +public class Xou_cfg_mgr { + private Xou_cfg_tbl tbl; + private final Hash_adp hash = Hash_adp_.New(); + private final Bry_bfr tmp_bfr = Bry_bfr_.New(); + public void Init_by_app(Db_conn conn) { + tbl = new Xou_cfg_tbl(conn); + tbl.Conn().Meta_tbl_assert(tbl); + this.Reg(tbl.Select_by_usr_ctx(Usr__anonymous, Ctx__app)); + } + public String Get_app_str_or(String key, String or) { // NOTE: app-level is always loaded at start; don't check db + synchronized (hash) { // LOCK:app-level + String uid = Bld_uid(tmp_bfr, Usr__anonymous, Ctx__app, key); + Xou_cfg_itm itm = (Xou_cfg_itm)hash.Get_by(uid); + return itm == null ? or : itm.Val(); + } + } + public void Set_app_bry(String key, byte[] val) {this.Set_app_str(key, String_.new_u8(val));} + public void Set_app_str(String key, String val) { + synchronized (hash) { // LOCK:app-level + // update val in reg + String uid = Bld_uid(tmp_bfr, Usr__anonymous, Ctx__app, key); + boolean insert = false; + Xou_cfg_itm itm = (Xou_cfg_itm)hash.Get_by(uid); + if (itm == null) { + itm = new Xou_cfg_itm(Usr__anonymous, Ctx__app, key, val); + hash.Add(uid, itm); + insert = true; + } + itm.Val_(val); + + // save to db + tbl.Upsert(insert, itm.Usr(), itm.Ctx(), itm.Key(), itm.Val()); + } + } + + private void Reg(Xou_cfg_itm[] itms) { + synchronized (hash) { // LOCK:app-level + for (Xou_cfg_itm itm : itms) + hash.Add(itm.Uid(), itm); + } + } + + private static final int Usr__anonymous = 1; + private static final String Ctx__app = "app"; + public static String Bld_uid(int usr, String ctx, String key) { + return String_.Concat(Int_.To_str(usr), "|", ctx, "|", key); + } + private static String Bld_uid(Bry_bfr tmp_bfr, int usr, String ctx, String key) { + tmp_bfr.Add_int_variable(usr).Add_byte_pipe(); + tmp_bfr.Add_str_a7(ctx).Add_byte_pipe(); + tmp_bfr.Add_str_u8(key); + return tmp_bfr.To_str_and_clear(); + } +} diff --git a/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_tbl.java b/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_tbl.java new file mode 100644 index 000000000..7380ffde2 --- /dev/null +++ b/400_xowa/src/gplx/xowa/users/cfgs/Xou_cfg_tbl.java @@ -0,0 +1,70 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.users.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*; +import gplx.dbs.*; +public class Xou_cfg_tbl implements Db_tbl { + public final Dbmeta_fld_list flds = new Dbmeta_fld_list(); + private final String fld_key, fld_usr, fld_ctx, fld_val; + public Xou_cfg_tbl(Db_conn conn) { + this.conn = conn; + this.fld_usr = flds.Add_int ("cfg_usr"); // EX: 1=anonymous; others will require usr_regy + this.fld_ctx = flds.Add_str ("cfg_ctx", 1024); // EX: "app"; "en.w" + this.fld_key = flds.Add_str ("cfg_key", 1024); // EX: "xowa.net.web_enabled" + this.fld_val = flds.Add_str ("cfg_val", 4096); // EX: "y" + conn.Rls_reg(this); + } + public Db_conn Conn() {return conn;} private final Db_conn conn; + public String Tbl_name() {return tbl_name;} private final String tbl_name = "user_cfg"; + public void Create_tbl() { + conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds + , Dbmeta_idx_itm.new_normal_by_tbl(tbl_name, fld_key, fld_key) + )); + } + public void Upsert(boolean insert, int usr, String ctx, String key, String val) { + if (insert) + Insert(usr, ctx, key, val); + else + Update(usr, ctx, key, val); + } + private void Insert(int usr, String ctx, String key, String val) { + Db_stmt stmt = conn.Stmt_insert(tbl_name, flds); + stmt.Clear().Val_int(fld_usr, usr).Val_str(fld_ctx, ctx).Val_str(fld_key, key).Val_str(fld_val, val).Exec_insert(); + stmt.Rls(); + } + private void Update(int usr, String ctx, String key, String val) { + Db_stmt stmt = conn.Stmt_update(tbl_name, String_.Ary(fld_usr, fld_ctx, fld_key), fld_val); + stmt.Clear().Val_str(fld_val, val).Crt_int(fld_usr, usr).Crt_str(fld_ctx, ctx).Crt_str(fld_key, key).Exec_update(); + stmt.Rls(); + } + public Xou_cfg_itm[] Select_by_usr_ctx(int usr, String ctx) { + List_adp list = List_adp_.New(); + Db_stmt stmt_select = conn.Stmt_select(tbl_name, flds, fld_usr, fld_ctx); + Db_rdr rdr = stmt_select.Clear().Crt_int(fld_usr, usr).Crt_str(fld_ctx, ctx).Exec_select__rls_auto(); + try { + while (rdr.Move_next()) { + list.Add(Make_itm(rdr)); + } + } finally {rdr.Rls();} + return (Xou_cfg_itm[])list.To_ary_and_clear(Xou_cfg_itm.class); + } + public void Rls() {} + + private Xou_cfg_itm Make_itm(Db_rdr rdr) { + return new Xou_cfg_itm(rdr.Read_int(fld_usr), rdr.Read_str(fld_ctx), rdr.Read_str(fld_key), rdr.Read_str(fld_val)); + } +} diff --git a/400_xowa/src/gplx/xowa/users/data/Xou_db_mgr.java b/400_xowa/src/gplx/xowa/users/data/Xou_db_mgr.java index 0be81f79e..398332704 100644 --- a/400_xowa/src/gplx/xowa/users/data/Xou_db_mgr.java +++ b/400_xowa/src/gplx/xowa/users/data/Xou_db_mgr.java @@ -18,7 +18,7 @@ along with this program. If not, see . package gplx.xowa.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*; import gplx.core.threads.*; import gplx.dbs.*; import gplx.dbs.metas.updates.*; import gplx.dbs.metas.*; import gplx.xowa.files.caches.*; -import gplx.xowa.users.bmks.*; import gplx.xowa.users.history.*; +import gplx.xowa.users.cfgs.*; import gplx.xowa.users.bmks.*; import gplx.xowa.users.history.*; public class Xou_db_mgr { private final Xoa_app app; private final Xoud_id_mgr id_mgr; @@ -35,6 +35,7 @@ public class Xou_db_mgr { public Xoud_bmk_mgr Bmk_mgr() {return bmk_mgr;} private final Xoud_bmk_mgr bmk_mgr = new Xoud_bmk_mgr(); public Xou_cache_mgr Cache_mgr() {return cache_mgr;} private Xou_cache_mgr cache_mgr; public Xou_file_itm_finder File__xfer_itm_finder() {return xfer_itm_finder;} private Xou_file_itm_finder xfer_itm_finder; + public Xou_cfg_mgr Cfg() {return cfg;} private final Xou_cfg_mgr cfg = new Xou_cfg_mgr(); public void Init_by_app(boolean drd, Io_url db_url) { Db_conn_bldr_data db_conn_bldr = Db_conn_bldr.Instance.Get_or_new(db_url); this.conn = db_conn_bldr.Conn(); boolean created = db_conn_bldr.Created(); @@ -42,6 +43,7 @@ public class Xou_db_mgr { this.cache_mgr = new Xou_cache_mgr(app.Wiki_mgri(), app.Fsys_mgr().File_dir(), db_file); this.xfer_itm_finder = new Xou_file_itm_finder(cache_mgr); this.bmk_mgr.Conn_(conn, created); + cfg.Init_by_app(conn); // this.history_mgr.Conn_(conn, created); if (drd) { this.Init_site_mgr(); diff --git a/400_xowa/src/gplx/xowa/users/history/Xou_history_html.java b/400_xowa/src/gplx/xowa/users/history/Xou_history_html.java index e3ef0fbe7..b87af43e5 100644 --- a/400_xowa/src/gplx/xowa/users/history/Xou_history_html.java +++ b/400_xowa/src/gplx/xowa/users/history/Xou_history_html.java @@ -24,7 +24,7 @@ public class Xou_history_html implements gplx.core.brys.Bfr_arg, Xow_special_pag Xowe_wiki wiki = (Xowe_wiki)wikii; Xoae_page page = (Xoae_page)pagei; this.app = wiki.Appe(); this.mgr = app.Usere().History_mgr(); mgr.Sort(); - Bry_bfr bfr = app.Utl__bfr_mkr().Get_m001(); + Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_m001(); html_grp.Bld_bfr_many(bfr, this); page.Db().Text().Text_bry_(bfr.To_bry_and_rls()); } diff --git a/400_xowa/src/gplx/xowa/wikis/Xowv_wiki.java b/400_xowa/src/gplx/xowa/wikis/Xowv_wiki.java index 20afb76a0..c1863507a 100644 --- a/400_xowa/src/gplx/xowa/wikis/Xowv_wiki.java +++ b/400_xowa/src/gplx/xowa/wikis/Xowv_wiki.java @@ -100,6 +100,7 @@ public class Xowv_wiki implements Xow_wiki, Xow_ttl_parser, Gfo_invk { data_mgr__core_mgr.Db__core().Tbl__ns().Select_all(ns_mgr); data_mgr__core_mgr.Db__core().Tbl__site_stats().Select(stats); html__hdump_mgr.Init_by_db(this); + app.Addon_mgr().Load_by_wiki(this); } public void Init_by_wiki__force() {init_needed = true; Init_by_wiki();} public void Init_by_make(Xowd_core_db_props props, gplx.xowa.bldrs.infos.Xob_info_session info_session) { diff --git a/400_xowa/src/gplx/xowa/wikis/caches/Xow_cache_mgr.java b/400_xowa/src/gplx/xowa/wikis/caches/Xow_cache_mgr.java index 7b0d0ce7d..31dc59ef5 100644 --- a/400_xowa/src/gplx/xowa/wikis/caches/Xow_cache_mgr.java +++ b/400_xowa/src/gplx/xowa/wikis/caches/Xow_cache_mgr.java @@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.wikis.caches; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; +import gplx.core.caches.*; import gplx.xowa.wikis.xwikis.sitelinks.*; public class Xow_cache_mgr { private final Xowe_wiki wiki; @@ -30,7 +31,12 @@ public class Xow_cache_mgr { public Xow_defn_cache Defn_cache() {return defn_cache;} private final Xow_defn_cache defn_cache; public Xow_defn_cache Lst_cache() {return lst_cache;} private final Xow_defn_cache lst_cache; public Hash_adp Misc_cache() {return misc_cache;} private final Hash_adp misc_cache = Hash_adp_.New(); - public void Page_cache_(Xow_page_cache v) {this.page_cache = v;} + public Gfo_cache_mgr Commons_cache() {return commons_cache;} private Gfo_cache_mgr commons_cache = new Gfo_cache_mgr().Max_size_(64 * Io_mgr.Len_mb).Reduce_by_(32 * Io_mgr.Len_mb); + public Gfo_cache_mgr Ifexist_cache() {return ifexist_cache;} private Gfo_cache_mgr ifexist_cache = new Gfo_cache_mgr().Max_size_(64 * Io_mgr.Len_mb).Reduce_by_(32 * Io_mgr.Len_mb); + + public Xow_cache_mgr Page_cache_(Xow_page_cache v) {this.page_cache = v; return this;} + public Xow_cache_mgr Commons_cache_(Gfo_cache_mgr v) {this.commons_cache = v; return this;} + public Xow_cache_mgr Ifexist_cache_(Gfo_cache_mgr v) {this.ifexist_cache = v; return this;} public Keyval[] Scrib_lang_names() { if (scrib_lang_names == null) { List_adp list = List_adp_.New(); @@ -47,7 +53,12 @@ public class Xow_cache_mgr { } public void Free_mem_all() {this.Free_mem_all(Bool_.Y);} public void Free_mem_all(boolean free_page_cache) { - if (free_page_cache) page_cache.Free_mem_all(); + if (free_page_cache) { + page_cache.Free_mem_all(); + commons_cache.Clear(); + ifexist_cache.Clear(); + wiki.Appe().Wiki_mgr().Wdata_mgr().Clear(); // moved from ctx.Clear(); DATE:2016-07-21 + } tmpl_result_cache.Clear(); defn_cache.Free_mem_all(); misc_cache.Clear(); diff --git a/400_xowa/src/gplx/xowa/wikis/caches/Xow_defn_cache.java b/400_xowa/src/gplx/xowa/wikis/caches/Xow_defn_cache.java index 6b7b275f3..27af9b85a 100644 --- a/400_xowa/src/gplx/xowa/wikis/caches/Xow_defn_cache.java +++ b/400_xowa/src/gplx/xowa/wikis/caches/Xow_defn_cache.java @@ -27,7 +27,6 @@ public class Xow_defn_cache { // stores compiled Xot_defn public Xow_defn_cache(Xol_lang_itm lang) {this.lang = lang;} public Xot_defn Get_by_key(byte[] name) {return (Xot_defn)cache.Get_by_key(name);} public void Free_mem_all() {cache.Clear();} - public void Free_mem_some() {cache.Reduce_recent();} public void Add(Xot_defn defn, byte case_match) { byte[] name = defn.Name(); int cache_size = defn.Cache_size(); // OBSOLETE: * 2 b/c it has src and root; diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_pid_tbl.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_pid_tbl.java index a2a4dca01..6afa00483 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_pid_tbl.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_pid_tbl.java @@ -49,7 +49,15 @@ public class Xowd_wbase_pid_tbl implements Rls_able { if (!rdr.Move_next()) return Wdata_wiki_mgr.Pid_null; // occurs when pid exists, but does not have entry for language; see hu.w:Marco Polo argali; DATE: 2014-02-01 byte[] pid_bry = rdr.Read_bry_by_str(fld_trg_ttl); return pid_bry == null ? Wdata_wiki_mgr.Pid_null : Bry_.To_int_or(pid_bry, 1, pid_bry.length, Wdata_wiki_mgr.Pid_null); - } finally {rdr.Rls();} + } + catch (Exception e) { + Gfo_usr_dlg_.Instance.Warn_many("", "", "db.wdata_pids:failed to select pid; lang=~{0} src_ttl=~{1} err=~{2}", src_lang, src_ttl, Err_.Message_gplx_log(e)); + try {stmt_select.Rls();} + catch (Exception e2) {Gfo_usr_dlg_.Instance.Warn_many("", "", "db.wdata_pids: failed to rls stmt; err=~{0}", Err_.Message_gplx_log(e2));} + stmt_select = null; + return Wdata_wiki_mgr.Pid_null; + } + finally {rdr.Rls();} } public void Rls() { stmt_insert = Db_stmt_.Rls(stmt_insert); diff --git a/400_xowa/src/gplx/xowa/wikis/pages/Xow_page_mgr.java b/400_xowa/src/gplx/xowa/wikis/pages/Xow_page_mgr.java index 8f3e2a0aa..1be8c419e 100644 --- a/400_xowa/src/gplx/xowa/wikis/pages/Xow_page_mgr.java +++ b/400_xowa/src/gplx/xowa/wikis/pages/Xow_page_mgr.java @@ -164,7 +164,7 @@ public class Xow_page_mgr implements Gfo_invk { Xoa_ttl trg_ttl = Xoa_ttl.Parse(wiki, page_bry); Xoa_url trg_url = Xoa_url.New(wiki.Domain_bry(), page_bry); page.Ttl_(trg_ttl).Url_(trg_url); - page.Redirect().Itms__add__special(trg_url, trg_ttl); + page.Redirect().Itms__add__article(trg_url, trg_ttl, null); wiki.Data_mgr().Load_from_db(page, trg_ttl.Ns(), trg_ttl, trg_url.Qargs_mgr().Match(Xoa_url_.Qarg__redirect, Xoa_url_.Qarg__redirect__no)); } diff --git a/400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_data.java b/400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_mgr.java similarity index 65% rename from 400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_data.java rename to 400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_mgr.java index 224c26555..b5c653ee6 100644 --- a/400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_data.java +++ b/400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_mgr.java @@ -16,14 +16,36 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.wikis.pages.redirects; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.pages.*; -public class Xopg_redirect_data { +import gplx.xowa.specials.*; +public class Xopg_redirect_mgr { private final List_adp itms = List_adp_.New(); public int Itms__len() {return itms.Len();} public byte[] Itms__get_at_0th_or_null() {return itms.Len() == 0 ? null : this.Itms__get_at(0).Wikitext();} public Xopg_redirect_itm Itms__get_at_nth_or_null() {return itms.Len() == 0 ? null : (Xopg_redirect_itm)itms.Get_at(itms.Len() - 1);} public Xopg_redirect_itm Itms__get_at(int i) {return (Xopg_redirect_itm)itms.Get_at(i);} public void Itms__add__article(Xoa_url url, Xoa_ttl ttl, byte[] wikitext) {Itms__add(url, ttl, wikitext);} - public void Itms__add__special(Xoa_url url, Xoa_ttl ttl) {Itms__add(url, ttl, null);} + public void Itms__add__special(Xow_wiki wiki, Xow_special_meta meta, Keyval... url_args) { + // build url and include args if available + byte[] url_bry = meta.Ttl_bry(); + int url_args_len = url_args.length; + if (url_args_len > 0) { + Bry_bfr bfr = Bry_bfr_.New(); + bfr.Add(url_bry); + for (int i = 0; i < url_args_len; ++i) { + Keyval url_arg = url_args[i]; + bfr.Add_byte(i == 0 ? Byte_ascii.Question : Byte_ascii.Amp); + bfr.Add_str_u8(url_arg.Key()); + bfr.Add_byte(Byte_ascii.Eq); + bfr.Add_obj(url_arg.Val()); + } + url_bry = bfr.To_bry_and_clear(); + } + + // create objects and add to list + Xoa_url url = wiki.Utl__url_parser().Parse(url_bry); + Xoa_ttl ttl = wiki.Ttl_parse(meta.Ttl_bry()); + this.Itms__add(url, ttl, null); + } private void Itms__add(Xoa_url url, Xoa_ttl ttl, byte[] wikitext) { Xopg_redirect_itm itm = new Xopg_redirect_itm(url, ttl, wikitext); itms.Add(itm); diff --git a/400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_mgr__tst.java b/400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_mgr__tst.java new file mode 100644 index 000000000..d4ea07e8a --- /dev/null +++ b/400_xowa/src/gplx/xowa/wikis/pages/redirects/Xopg_redirect_mgr__tst.java @@ -0,0 +1,53 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.wikis.pages.redirects; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.pages.*; +import org.junit.*; import gplx.core.tests.*; import gplx.xowa.specials.*; +public class Xopg_redirect_mgr__tst { + @Before public void init() {fxt.Clear();} private final Xopg_redirect_mgr__fxt fxt = new Xopg_redirect_mgr__fxt(); + @Test public void Basic() { + fxt.Test__Itms__add__special(fxt.Make_meta("XowaTest"), Keyval_.Ary_empty, fxt.Make__itm("en.wikipedia.org/wiki/Special:XowaTest", "Special:XowaTest", null)); + } + @Test public void Args() { + fxt.Test__Itms__add__special + ( fxt.Make_meta("XowaTest"), Keyval_.Ary(Keyval_.new_("k1", "v1"), Keyval_.new_("k2", "v2"), Keyval_.new_("k3", "v3")) + , fxt.Make__itm("en.wikipedia.org/wiki/Special:XowaTest?k1=v1&k2=v2&k3=v3", "Special:XowaTest", null) + ); + } +} +class Xopg_redirect_mgr__fxt { + private Xow_wiki wiki; + private final Xopg_redirect_mgr mgr = new Xopg_redirect_mgr(); + public void Clear() { + mgr.Clear(); + Xoae_app app = Xoa_app_fxt.Make__app__edit(); + this.wiki = Xoa_app_fxt.Make__wiki__edit(app); + } + public Xow_special_meta Make_meta(String key) {return Xow_special_meta.New_xo(key, "test display name");} + public Xopg_redirect_itm Make__itm(String url_str, String ttl_str, String wikitext) { + Xoa_url url = wiki.Utl__url_parser().Parse(Bry_.new_u8(url_str)); + Xoa_ttl ttl = wiki.Ttl_parse(Bry_.new_u8(ttl_str)); + return new Xopg_redirect_itm(url, ttl, Bry_.new_u8_safe(wikitext)); + } + public void Test__Itms__add__special(Xow_special_meta meta, Keyval[] url_args, Xopg_redirect_itm expd) { + mgr.Itms__add__special(wiki, meta, url_args); + Xopg_redirect_itm actl = mgr.Itms__get_at(0); + Gftest.Eq__bry(expd.Ttl().Raw(), actl.Ttl().Raw(), "ttl"); + Gftest.Eq__str(expd.Url().To_str(), actl.Url().To_str(), "url"); + Gftest.Eq__bry(expd.Wikitext(), actl.Wikitext(), "wikitext"); + } +} diff --git a/400_xowa/src/gplx/xowa/wikis/tdbs/Xotdb_fsys_mgr.java b/400_xowa/src/gplx/xowa/wikis/tdbs/Xotdb_fsys_mgr.java index 55d60f27f..d16dddcf2 100644 --- a/400_xowa/src/gplx/xowa/wikis/tdbs/Xotdb_fsys_mgr.java +++ b/400_xowa/src/gplx/xowa/wikis/tdbs/Xotdb_fsys_mgr.java @@ -79,17 +79,5 @@ public class Xotdb_fsys_mgr { return rv; } public static Io_url Url_fil(Io_url root_dir, int fil_idx, byte[] ext) {return Xos_url_gen.bld_fil_(root_dir, fil_idx, ext);} private static final String Const_url_cfg = "cfg"; - public static Io_url Find_file_or_fail(Io_url dir, String file_name, String file_ext_0, String file_ext_1) { - Io_url url = Find_file_or_null(dir, file_name, file_ext_0, file_ext_1); - if (url == null) throw Err_.new_wo_type("could not find file", "dir", dir.Raw(), "name", file_name, "ext_0", file_ext_0, "ext_1", file_ext_1); - return url; - } - public static Io_url Find_file_or_null(Io_url dir, String file_name, String file_ext_0, String file_ext_1) { - Io_url url = Xob_page_wkr_cmd.Find_fil_by(dir, file_name + file_ext_0); - if (url == null) { - url = Xob_page_wkr_cmd.Find_fil_by(dir, file_name + file_ext_1); - if (url == null) return null; - } - return url; - } + } diff --git a/400_xowa/src/gplx/xowa/xtns/Xox_mgr_base.java b/400_xowa/src/gplx/xowa/xtns/Xox_mgr_base.java index c96cf1a80..ea9f73b95 100644 --- a/400_xowa/src/gplx/xowa/xtns/Xox_mgr_base.java +++ b/400_xowa/src/gplx/xowa/xtns/Xox_mgr_base.java @@ -26,7 +26,7 @@ public abstract class Xox_mgr_base implements Xox_mgr { public boolean Enabled() {return enabled;} private boolean enabled; @gplx.Virtual public boolean Enabled_default() {return true;} public void Enabled_y_() {enabled = true; enabled_manually = true;} public void Enabled_n_() {enabled = false; enabled_manually = true;} // TEST: - public void Enabled_(boolean v) {enabled = v;} + @gplx.Virtual public void Enabled_(boolean v) {enabled = v;} public boolean Enabled_manually() {return enabled_manually;} private boolean enabled_manually; public abstract Xox_mgr Xtn_clone_new(); @gplx.Virtual public void Xtn_ctor_by_app(Xoae_app app) {} @@ -36,7 +36,7 @@ public abstract class Xox_mgr_base implements Xox_mgr { @gplx.Virtual public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_enabled)) return Yn.To_str(enabled); - else if (ctx.Match(k, Invk_enabled_)) {enabled = m.ReadYn("v"); enabled_manually = true;} + else if (ctx.Match(k, Invk_enabled_)) {this.Enabled_(m.ReadYn("v")); enabled_manually = true;} else return Gfo_invk_.Rv_unhandled; return this; } diff --git a/400_xowa/src/gplx/xowa/xtns/cites/Cite_xtn_mgr.java b/400_xowa/src/gplx/xowa/xtns/cites/Cite_xtn_mgr.java index a821dfbdd..034d369dd 100644 --- a/400_xowa/src/gplx/xowa/xtns/cites/Cite_xtn_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/cites/Cite_xtn_mgr.java @@ -18,8 +18,6 @@ along with this program. If not, see . package gplx.xowa.xtns.cites; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; public class Cite_xtn_mgr extends Xox_mgr_base { @Override public byte[] Xtn_key() {return XTN_KEY;} public static final byte[] XTN_KEY = Bry_.new_a7("cite"); -// public byte[] Group_default_name() {return group_default_name;} private byte[] group_default_name = Bry_.new_a7("lower-alpha"); - public static byte[] Group_default_name() {return group_default_name;} private static byte[] group_default_name = Bry_.new_a7("lower-alpha"); @Override public Xox_mgr Xtn_clone_new() {return new Cite_xtn_mgr();} @Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_group_default_name)) return String_.new_u8(group_default_name); @@ -28,4 +26,6 @@ public class Cite_xtn_mgr extends Xox_mgr_base { return this; } private static final String Invk_group_default_name = "group_default_name", Invk_group_default_name_ = "group_default_name_"; + + public static byte[] Group_default_name() {return group_default_name;} private static byte[] group_default_name = Bry_.new_a7("lower-alpha"); } diff --git a/400_xowa/src/gplx/xowa/xtns/cites/Ref_html_wtr.java b/400_xowa/src/gplx/xowa/xtns/cites/Ref_html_wtr.java index f2dd7f365..6ea857782 100644 --- a/400_xowa/src/gplx/xowa/xtns/cites/Ref_html_wtr.java +++ b/400_xowa/src/gplx/xowa/xtns/cites/Ref_html_wtr.java @@ -21,6 +21,7 @@ import gplx.xowa.htmls.*; import gplx.xowa.htmls.core.htmls.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.xndes.*; public class Ref_html_wtr { private final Xoh_ref_list_fmtr grp_list_fmtr = new Xoh_ref_list_fmtr(); + private final Bfr_arg__bry_fmtr grp_key_fmtr = Bfr_arg_.New_bry_fmtr__null(), itm_id_fmtr = Bfr_arg_.New_bry_fmtr__null(), grp_id_fmtr = Bfr_arg_.New_bry_fmtr__null(); public Ref_html_wtr(Xowe_wiki wiki) { cfg = Ref_html_wtr_cfg.new_(); } @@ -37,7 +38,7 @@ public class Ref_html_wtr { ? itm.Idx_major() + 1 : (Object)grp_key_fmtr.Set(cfg.Itm_grp_text(), itm.Group(), itm.Idx_major() + 1) ); - } private Bfr_arg__bry_fmtr grp_key_fmtr = Bfr_arg_.New_bry_fmtr__null(); + } public Ref_html_wtr_cfg Cfg() {return cfg;} private Ref_html_wtr_cfg cfg; public void Init_by_wiki(Xowe_wiki wiki) { cfg.Init_by_wiki(wiki); @@ -51,12 +52,12 @@ public class Ref_html_wtr { else return itm_id_fmtr.Set(cfg.Itm_id_key_many(), itm.Name(), itm.Idx_major()); } - } private Bfr_arg__bry_fmtr itm_id_fmtr = Bfr_arg_.New_bry_fmtr__null(); + } private Bfr_arg Grp_id(Ref_nde itm) { return itm.Name() == Bry_.Empty // name is blank >>> uid ? grp_id_fmtr.Set(cfg.Grp_id_uid(), itm.Uid()) : grp_id_fmtr.Set(cfg.Grp_id_key(), itm.Name(), itm.Idx_major()); - } private Bfr_arg__bry_fmtr grp_id_fmtr = Bfr_arg_.New_bry_fmtr__null(); + } private int List_len(Ref_nde itm) { int len = itm.Related_len(); int rv = len; diff --git a/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_grp.java b/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_grp.java index a3d0c7eca..4fc2b359c 100644 --- a/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_grp.java +++ b/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_grp.java @@ -17,14 +17,15 @@ along with this program. If not, see . */ package gplx.xowa.xtns.cites; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; public class Ref_itm_grp { - private List_adp lsts = List_adp_.New(); + private final List_adp lsts = List_adp_.New(); + private int lst_idx; public Ref_itm_grp(byte[] grp_name) {this.grp_name = grp_name;} public byte[] Grp_name() {return grp_name;} private byte[] grp_name; public int Grp_seal() { if (lst_idx == lsts.Count()) // NOTE: lst_idx == lsts.Count() if there are no itms in lst; need to add placeholder list anyway; nodes has a List_index, which will call lsts.Get_at(); see Empty_group_before_ref lsts.Add(new Ref_itm_lst(grp_name)); return lst_idx++; - } int lst_idx; + } public int Lsts_len() {return lsts.Count();} public Ref_itm_lst Lsts_get_at(int i) {return i < lsts.Count() ? (Ref_itm_lst)lsts.Get_at(i) : null;} // NOTE: null can be returned; see Infobox planet; w:Mars public void Lsts_add(byte[] itm_name, byte[] follow, Ref_nde itm) { diff --git a/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_lst.java b/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_lst.java index b6d87f24f..75bc2d642 100644 --- a/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_lst.java +++ b/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_lst.java @@ -17,8 +17,11 @@ along with this program. If not, see . */ package gplx.xowa.xtns.cites; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; public class Ref_itm_lst { - public Ref_itm_lst(byte[] grp_name) {this.grp_name = grp_name;} - byte[] grp_name; int idx_major_last = 0; + private final Hash_adp hash = Hash_adp_bry.cs(); + private final List_adp list = List_adp_.New(); + private int idx_major_last = 0; + // private byte[] grp_name; + public Ref_itm_lst(byte[] grp_name) {} //this.grp_name = grp_name; public int Itms_len() {return list.Count();} public Ref_nde Itms_get_at(int i) {return (Ref_nde)list.Get_at(i);} public void Itms_add(byte[] itm_name, byte[] follow, Ref_nde itm) { @@ -59,5 +62,4 @@ public class Ref_itm_lst { list.Clear(); idx_major_last = 0; } - Hash_adp hash = Hash_adp_bry.cs(); List_adp list = List_adp_.New(); } diff --git a/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_mgr.java b/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_mgr.java index adbf37061..777ee5a10 100644 --- a/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/cites/Ref_itm_mgr.java @@ -17,8 +17,8 @@ along with this program. If not, see . */ package gplx.xowa.xtns.cites; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; public class Ref_itm_mgr { - private Hash_adp_bry grps = Hash_adp_bry.cs(); // CASE_MATCH:changed from ci; DATE:2014-07-07 - private Ref_itm_grp grp_default = new Ref_itm_grp(Bry_.Empty); + private final Hash_adp_bry grps = Hash_adp_bry.cs(); // CASE_MATCH:changed from ci; DATE:2014-07-07 + private final Ref_itm_grp grp_default = new Ref_itm_grp(Bry_.Empty); private int uid_last; public boolean References__recursing() {return references__recursing;} public void References__recursing_(boolean v) {references__recursing = v;} private boolean references__recursing; public Ref_itm_lst Lst_get(byte[] grp_name, int lst_idx) { diff --git a/400_xowa/src/gplx/xowa/xtns/cites/Ref_nde.java b/400_xowa/src/gplx/xowa/xtns/cites/Ref_nde.java index 406dc69cf..b7b5989bf 100644 --- a/400_xowa/src/gplx/xowa/xtns/cites/Ref_nde.java +++ b/400_xowa/src/gplx/xowa/xtns/cites/Ref_nde.java @@ -59,7 +59,6 @@ public class Ref_nde implements Xox_xnde, Mwh_atr_itm_owner1 { public void Xtn_write(Bry_bfr bfr, Xoae_app app, Xop_ctx ctx, Xoh_html_wtr html_wtr, Xoh_wtr_ctx hctx, Xoae_page wpg, Xop_xnde_tkn xnde, byte[] src) { html_wtr.Ref_wtr().Xnde_ref(hctx, bfr, src, xnde); } - private static final Ref_nde[] Ary_empty = new Ref_nde[0]; public Ref_nde[] Related() {return related;} Ref_nde[] related = Ary_empty; public int Related_len() {return related_len;} private int related_len; public Ref_nde Related_get(int i) {return related[i];} @@ -74,6 +73,7 @@ public class Ref_nde implements Xox_xnde, Mwh_atr_itm_owner1 { } public static final int Idx_minor_follow = -2; public static final byte Xatr_id_name = 0, Xatr_id_group = 1, Xatr_id_follow = 2; + private static final Ref_nde[] Ary_empty = new Ref_nde[0]; private static final Hash_adp_bry xatrs_hash = Hash_adp_bry.ci_a7() .Add_str_obj("name", Byte_obj_val.new_(Ref_nde.Xatr_id_name)) .Add_str_obj("group", Byte_obj_val.new_(Ref_nde.Xatr_id_group)) diff --git a/400_xowa/src/gplx/xowa/xtns/flaggedRevs/scribunto/Flagged_revs_lib.java b/400_xowa/src/gplx/xowa/xtns/flaggedRevs/scribunto/Flagged_revs_lib.java index 65f29d0e2..ce6973cac 100644 --- a/400_xowa/src/gplx/xowa/xtns/flaggedRevs/scribunto/Flagged_revs_lib.java +++ b/400_xowa/src/gplx/xowa/xtns/flaggedRevs/scribunto/Flagged_revs_lib.java @@ -23,13 +23,14 @@ public class Flagged_revs_lib implements Scrib_lib { 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 Scrib_lib Core_(Scrib_core v) {this.core = v; return this;} // TEST: + public Scrib_lib Clone_lib(Scrib_core core) {return new Flagged_revs_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("FlaggedRevs", "scribunto", "mw.ext.FlaggedRevs.lua")); return mod; } - public Scrib_proc_mgr Procs() {return procs;} private final Scrib_proc_mgr procs = new Scrib_proc_mgr(); + public Scrib_proc_mgr Procs() {return procs;} private final 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_getStabilitySettings: return GetStabilitySettings(args, rslt); @@ -38,7 +39,7 @@ public class Flagged_revs_lib implements Scrib_lib { } private static final int Proc_getStabilitySettings = 0; public static final String Invk_getStabilitySettings = "getStabilitySettings"; - private static final String[] Proc_names = String_.Ary(Invk_getStabilitySettings); + private static final String[] Proc_names = String_.Ary(Invk_getStabilitySettings); public boolean GetStabilitySettings(Scrib_proc_args args, Scrib_proc_rslt rslt) { byte[] page_name = args.Cast_bry_or_null(0); Xoa_ttl page_ttl = null; diff --git a/400_xowa/src/gplx/xowa/xtns/math/Xof_math_html_wtr.java b/400_xowa/src/gplx/xowa/xtns/math/Xof_math_html_wtr.java index 01a6e272d..e1eca42fd 100644 --- a/400_xowa/src/gplx/xowa/xtns/math/Xof_math_html_wtr.java +++ b/400_xowa/src/gplx/xowa/xtns/math/Xof_math_html_wtr.java @@ -20,29 +20,29 @@ import gplx.core.brys.fmtrs.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.core.htmls.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.vnts.*; public class Xof_math_html_wtr { - private Xof_math_itm tmp_math_itm = new Xof_math_itm(); - private Bry_fmtr math_fmtr_latex = Bry_fmtr.new_("~{math_text}", "math_idx", "math_text"); - private Bry_fmtr math_fmtr_mathjax = Bry_fmtr.new_("~{math_text}", "math_idx", "math_text"); + private final Bry_fmtr math_fmtr_latex = Bry_fmtr.new_("~{math_text}", "math_idx", "math_text"); + private final Bry_fmtr math_fmtr_mathjax = Bry_fmtr.new_("~{math_text}", "math_idx", "math_text"); public void Write(Xoh_html_wtr wtr, Xop_ctx ctx, Xoh_wtr_ctx opts, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde) { Xoae_app app = ctx.App(); Xowe_wiki wiki = ctx.Wiki(); Xoae_page page = ctx.Page(); boolean renderer_is_latex = !app.File_mgr().Math_mgr().Renderer_is_mathjax(); byte[] math_bry = Bry_.Mid(src, xnde.Tag_open_end(), xnde.Tag_close_bgn()); - Bry_bfr tmp_bfr = app.Utl__bfr_mkr().Get_b512().Mkr_rls(); + Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512().Mkr_rls(); math_bry = Escape_tex(tmp_bfr, !renderer_is_latex, math_bry); byte[] math_bry_clean = wiki.Html_mgr().Js_cleaner().Clean(wiki, math_bry, 0, math_bry.length); // check for js; if (math_bry_clean != null) math_bry = math_bry_clean; // js found; use clean version; DATE:2013-08-26 boolean enabled = app.File_mgr().Math_mgr().Enabled(); - if (renderer_is_latex && app.File_mgr().Math_mgr().Find_itm(tmp_math_itm, page.Wiki().Domain_str(), math_bry)) { + Xof_math_itm math_itm = ctx.Tmp_mgr().Math_itm(); + if (renderer_is_latex && app.File_mgr().Math_mgr().Find_itm(math_itm, page.Wiki().Domain_str(), math_bry)) { bfr.Add(Xoh_consts.Img_bgn); - bfr.Add_str_u8(tmp_math_itm.Png_url().To_http_file_str()); + bfr.Add_str_u8(math_itm.Png_url().To_http_file_str()); bfr.Add(Xoh_consts.__inline_quote); } else - Write_for_mathjax(bfr, page, enabled, renderer_is_latex, math_bry, tmp_bfr); + Write_for_mathjax(bfr, page, enabled, renderer_is_latex, math_bry, tmp_bfr, math_itm); } - private void Write_for_mathjax(Bry_bfr bfr, Xoae_page page, boolean enabled, boolean renderer_is_latex, byte[] math_bry, Bry_bfr tmp_bfr) { + private void Write_for_mathjax(Bry_bfr bfr, Xoae_page page, boolean enabled, boolean renderer_is_latex, byte[] math_bry, Bry_bfr tmp_bfr, Xof_math_itm math_itm) { int id = page.File_math().Count(); - Xof_math_itm new_math_itm = tmp_math_itm.Clone().Id_(id); + Xof_math_itm new_math_itm = math_itm.Clone().Id_(id); Bry_fmtr math_fmtr = renderer_is_latex ? math_fmtr_latex : math_fmtr_mathjax; boolean armor_math = page.Lang().Vnt_mgr().Enabled() && !renderer_is_latex; // REF.MW:LangConverter.php|armourMath if (armor_math) bfr.Add(Vnt_convert_lang.Bry__armor_bgn); diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/Pf_func_.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/Pf_func_.java index c398d7bd1..ec3c8b92a 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/Pf_func_.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/Pf_func_.java @@ -43,8 +43,7 @@ public class Pf_func_ { nde.Val_tkn().Tmpl_evaluate(ctx, src, caller, bfr); return bfr.To_bry_and_clear_and_trim(); } - private static final Number_parser lhs_parser = new Number_parser().Hex_enabled_(true), rhs_parser = new Number_parser().Hex_enabled_(true); - public static boolean Eq_(byte[] lhs, byte[] rhs) { // PATCH.PHP: php allows "003" == "3.0"; ASSUME: numbers are either int or int-like decimal; long, float, decimal not supported + public static boolean Eq(Xop_ctx ctx, byte[] lhs, byte[] rhs) { // PATCH.PHP: php allows "003" == "3.0"; ASSUME: numbers are either int or int-like decimal; long, float, decimal not supported int lhs_len = lhs.length, rhs_len = rhs.length; boolean rv = true; if (lhs_len == rhs_len) { @@ -58,13 +57,13 @@ public class Pf_func_ { } else if (lhs_len == 0 || rhs_len == 0) // one side is empty String and the other side is String; return false; return false; - synchronized (lhs_parser) { // LOCK:static-obj; DATE:2016-07-06 - lhs_parser.Parse(lhs, 0, lhs_len); - if (lhs_parser.Has_err()) return false; - rhs_parser.Parse(rhs, 0, rhs_len); - if (rhs_parser.Has_err()) return false; - return lhs_parser.Has_frac() || rhs_parser.Has_frac() ? lhs_parser.Rv_as_dec().Eq(rhs_parser.Rv_as_dec()) : lhs_parser.Rv_as_int() == rhs_parser.Rv_as_int(); - } + Number_parser lhs_parser = ctx.Tmp_mgr().Pfunc_num_parser_0(); + Number_parser rhs_parser = ctx.Tmp_mgr().Pfunc_num_parser_1(); + lhs_parser.Parse(lhs, 0, lhs_len); + if (lhs_parser.Has_err()) return false; + rhs_parser.Parse(rhs, 0, rhs_len); + if (rhs_parser.Has_err()) return false; + return lhs_parser.Has_frac() || rhs_parser.Has_frac() ? lhs_parser.Rv_as_dec().Eq(rhs_parser.Rv_as_dec()) : lhs_parser.Rv_as_int() == rhs_parser.Rv_as_int(); } public static void Reg(Xow_domain_itm domain_itm, gplx.xowa.langs.funcs.Xol_func_regy func_regy, Xol_lang_itm lang) { Xol_kwd_mgr kwd_mgr = lang.Kwd_mgr(); diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Func_tkn_stack.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Func_tkn_stack.java index 46774aaae..4fca7876d 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Func_tkn_stack.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Func_tkn_stack.java @@ -16,25 +16,24 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.xtns.pfuncs.exprs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*; -import gplx.xowa.parsers.*; class Func_tkn_stack { - public void Clear() {stack_len = 0;} - public int Len() {return stack_len;} - public Func_tkn GetLast() {return stack_len == 0 ? null : stack[stack_len - 1];} + private Func_tkn[] ary = new Func_tkn[0]; private int len = 0, max = 0; + public void Clear() {len = 0;} + public int Len() {return len;} + public Func_tkn Get_at_last() {return len == 0 ? null : ary[len - 1];} public Func_tkn Pop() { - int stack_len_new = stack_len - 1; - Func_tkn rv = stack[stack_len_new]; - stack_len = stack_len_new; + int new_len = len - 1; + Func_tkn rv = ary[new_len]; + len = new_len; return rv; } public void Push(Func_tkn v) { - int stack_len_new = stack_len + 1; - if (stack_len_new > stack_max) { - stack_max = stack_len_new * 2; - stack = (Func_tkn[])Array_.Resize(stack, stack_max); + int new_len = len + 1; + if (new_len > max) { + max = new_len * 2; + ary = (Func_tkn[])Array_.Resize(ary, max); } - stack[stack_len] = v; - stack_len = stack_len_new; + ary[len] = v; + len = new_len; } - Func_tkn[] stack = new Func_tkn[0]; int stack_len = 0, stack_max = 0; } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Pfunc_expr.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Pfunc_expr.java index 60f9d8e7d..0b43d300a 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Pfunc_expr.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Pfunc_expr.java @@ -25,6 +25,7 @@ public class Pfunc_expr extends Pf_func_base { Evaluate(bfr, ctx, val_dat_ary); } public static boolean Evaluate(Bry_bfr bfr, Xop_ctx ctx, byte[] expr) { + Pfunc_expr_shunter shunter = ctx.Tmp_mgr().Expr_shunter(); Decimal_adp rslt = shunter.Evaluate(ctx, expr); // NOTE: php uses "float" but really is a double; http://www.php.net/manual/en/language.types.float.php if (rslt == Pfunc_expr_shunter.Null_rslt) { bfr.Add_bfr_and_preserve(shunter.Err()); @@ -36,11 +37,10 @@ public class Pfunc_expr extends Pf_func_base { return true; } } - private static Pfunc_expr_shunter shunter = Pfunc_expr_shunter.Instance; @Override public int Id() {return Xol_kwd_grp_.Id_xtn_expr;} @Override public Pf_func New(int id, byte[] name) {return new Pfunc_expr().Name_(name);} } class Pfunc_expr_msg { - public static final Gfo_msg_grp Nde = Gfo_msg_grp_.new_(Xoa_app_.Nde, "expr"); - public static final Gfo_msg_itm Unknown = Gfo_msg_itm_.new_warn_(Nde, "unknown", "unknown"); + public static final Gfo_msg_grp Nde = Gfo_msg_grp_.new_(Xoa_app_.Nde, "expr"); + public static final Gfo_msg_itm Unknown = Gfo_msg_itm_.new_warn_(Nde, "unknown", "unknown"); } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Pfunc_expr_shunter.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Pfunc_expr_shunter.java index 9065c1cd6..74c78973f 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Pfunc_expr_shunter.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/exprs/Pfunc_expr_shunter.java @@ -20,12 +20,11 @@ import gplx.core.btries.*; import gplx.core.brys.fmtrs.*; import gplx.xowa.langs.*; import gplx.xowa.langs.msgs.*; import gplx.xowa.parsers.*; public class Pfunc_expr_shunter { - private Btrie_fast_mgr trie = expression_(); private final Btrie_rv trv = new Btrie_rv(); - Val_stack val_stack = new Val_stack(); - Func_tkn_stack prc_stack = new Func_tkn_stack(); - public static final Decimal_adp Null_rslt = null; - private final Object thread_lock = new Object(); - public Bry_bfr Err() {return err_bfr;} Bry_bfr err_bfr = Bry_bfr_.New(); + private final Btrie_fast_mgr trie = expression_(); private final Btrie_rv trv = new Btrie_rv(); + private final Val_stack val_stack = new Val_stack(); + private final Func_tkn_stack prc_stack = new Func_tkn_stack(); + private final Bry_fmtr tmp_fmtr = Bry_fmtr.tmp_(); + public Bry_bfr Err() {return err_bfr;} private final Bry_bfr err_bfr = Bry_bfr_.New(); public Decimal_adp Err_set(Xop_ctx ctx, int msgId) {return Err_set(ctx, msgId, Bry_.Empty);} public Decimal_adp Err_set(Xop_ctx ctx, int msg_id, byte[] arg) { byte[] msg_val = ctx.Wiki().Msg_mgr().Val_by_id(msg_id); @@ -33,136 +32,137 @@ public class Pfunc_expr_shunter { tmp_fmtr.Fmt_(msg_val).Bld_bfr_one(err_bfr, arg); err_bfr.Add(Err_end_ary); return Null_rslt; - } static final byte[] Err_bgn_ary = Bry_.new_a7(""), Err_end_ary = Bry_.new_a7(""); Bry_fmtr tmp_fmtr = Bry_fmtr.tmp_(); + } public void Rslt_set(byte[] bry) { err_bfr.Add(bry); } public Decimal_adp Evaluate(Xop_ctx ctx, byte[] src) { // REF.MW: Expr.php - synchronized (thread_lock) { - int src_len = src.length; if (src_len == 0) return Null_rslt; - int cur_pos = 0; byte cur_byt = src[0]; - boolean mode_expr = true; Func_tkn prv_prc = null; - val_stack.Clear(); prc_stack.Clear(); - while (true) { - // can't think of a way for this to happen; note that operators will automatically push values/operators off stack that are lower; can't get up to 100 - // if (val_stack.Len() > 100 || prc_stack.Len() > 100) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_err__stack_exhausted); - Object o = trie.Match_at_w_b0(trv, cur_byt, src, cur_pos, src_len); - int bgn_pos = cur_pos; - if (o == null) { // letter or unknown symbol - while (cur_pos < src_len) { - byte b = src[cur_pos++]; - if (Byte_ascii.Is_ltr(b)) - continue; - else - break; - } - return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unrecognised_word, Bry_.Mid(src, bgn_pos, cur_pos)); + int src_len = src.length; if (src_len == 0) return Null_rslt; + int cur_pos = 0; byte cur_byt = src[0]; + boolean mode_expr = true; Func_tkn prv_prc = null; + val_stack.Clear(); prc_stack.Clear(); + while (true) { + // can't think of a way for this to happen; note that operators will automatically push values/operators off stack that are lower; can't get up to 100 + // if (val_stack.Len() > 100 || prc_stack.Len() > 100) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_err__stack_exhausted); + Object o = trie.Match_at_w_b0(trv, cur_byt, src, cur_pos, src_len); + int bgn_pos = cur_pos; + if (o == null) { // letter or unknown symbol + while (cur_pos < src_len) { + byte b = src[cur_pos++]; + if (Byte_ascii.Is_ltr(b)) + continue; + else + break; } - else { - Expr_tkn t = (Expr_tkn)o; - cur_pos = trv.Pos(); - switch (t.Tid()) { - case Expr_tkn_.Tid_space: break; - case Expr_tkn_.Tid_number: - if (!mode_expr) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_number); - int numBgn = cur_pos - 1; - boolean loop = true; - while (loop) { - if (cur_pos == src_len) break; - switch (src[cur_pos]) { - case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4: - case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9: - case Byte_ascii.Dot: - ++cur_pos; - break; - default: loop = false; break; - } + return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unrecognised_word, Bry_.Mid(src, bgn_pos, cur_pos)); + } + else { + Expr_tkn t = (Expr_tkn)o; + cur_pos = trv.Pos(); + switch (t.Tid()) { + case Expr_tkn_.Tid_space: break; + case Expr_tkn_.Tid_number: + if (!mode_expr) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_number); + int numBgn = cur_pos - 1; + boolean loop = true; + while (loop) { + if (cur_pos == src_len) break; + switch (src[cur_pos]) { + case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4: + case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9: + case Byte_ascii.Dot: + ++cur_pos; + break; + default: loop = false; break; } - Decimal_adp num = Null_rslt; - try {num = Bry_.To_decimal(src, numBgn, cur_pos);} - catch (Exception exc) { - // NOTE: PATCH.PHP: 65.5.5 can evaluate to 65.5; EX "{{Geological eras|-600|height=2|border=none}}" eventually does "|10-to={{#ifexpr:{{{1|-4567}}}<-65.5|-65.5|{{{1}}}}}.5" which is 65.5.5 - Err_.Noop(exc); - int dot_count = 0; - for (int i = numBgn; i < cur_pos; i++) { - if (src[i] == Byte_ascii.Dot) { - switch (dot_count) { - case 0: dot_count = 1; break; - case 1: - try { - num = Bry_.To_decimal(src, numBgn, i); - } - catch (Exception exc_inner) {Err_.Noop(exc_inner);} - break; - } + } + Decimal_adp num = Null_rslt; + try {num = Bry_.To_decimal(src, numBgn, cur_pos);} + catch (Exception exc) { + // NOTE: PATCH.PHP: 65.5.5 can evaluate to 65.5; EX "{{Geological eras|-600|height=2|border=none}}" eventually does "|10-to={{#ifexpr:{{{1|-4567}}}<-65.5|-65.5|{{{1}}}}}.5" which is 65.5.5 + Err_.Noop(exc); + int dot_count = 0; + for (int i = numBgn; i < cur_pos; i++) { + if (src[i] == Byte_ascii.Dot) { + switch (dot_count) { + case 0: dot_count = 1; break; + case 1: + try { + num = Bry_.To_decimal(src, numBgn, i); + } + catch (Exception exc_inner) {Err_.Noop(exc_inner);} + break; } } - if (num == null) return Null_rslt; } - val_stack.Push(num); - mode_expr = false; - break; - case Expr_tkn_.Tid_paren_lhs: - if (!mode_expr) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_operator, Bry_.new_a7("(")); - prc_stack.Push((Func_tkn)t); - break; - case Expr_tkn_.Tid_operator: - Func_tkn cur_prc = (Func_tkn)t; - if (Byte_ascii.Is_ltr(cur_byt)) { - int nxt_pos = Bry_find_.Find_fwd_while_letter(src, cur_pos, src_len); - if (nxt_pos > cur_pos) - return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unrecognised_word, Bry_.Mid(src, bgn_pos, nxt_pos)); - } - if (cur_prc.Func_is_const()) { // func is "pi" or "e"; DATE:2014-03-01 - if (mode_expr) { // number expected; just call Calc (which will place value on stack) - cur_prc.Calc(ctx, this, val_stack); - break; - } - else // operator expected; fail b/c pi / e is not an operator; - return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_number); - } - if (mode_expr) { // NOTE: all the GetAlts have higher precedence; "break;" need to skip evaluation below else will fail for --1 - Func_tkn alt_prc = cur_prc.GetAlt(); - prc_stack.Push(alt_prc); + if (num == null) return Null_rslt; + } + val_stack.Push(num); + mode_expr = false; + break; + case Expr_tkn_.Tid_paren_lhs: + if (!mode_expr) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_operator, Bry_.new_a7("(")); + prc_stack.Push((Func_tkn)t); + break; + case Expr_tkn_.Tid_operator: + Func_tkn cur_prc = (Func_tkn)t; + if (Byte_ascii.Is_ltr(cur_byt)) { + int nxt_pos = Bry_find_.Find_fwd_while_letter(src, cur_pos, src_len); + if (nxt_pos > cur_pos) + return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unrecognised_word, Bry_.Mid(src, bgn_pos, nxt_pos)); + } + if (cur_prc.Func_is_const()) { // func is "pi" or "e"; DATE:2014-03-01 + if (mode_expr) { // number expected; just call Calc (which will place value on stack) + cur_prc.Calc(ctx, this, val_stack); break; } - prv_prc = prc_stack.GetLast(); - while (prv_prc != null && (cur_prc.Precedence() <= prv_prc.Precedence())) { - if (!prv_prc.Calc(ctx, this, val_stack)) return Null_rslt; - prc_stack.Pop(); - prv_prc = prc_stack.GetLast(); - } - prc_stack.Push(cur_prc); - mode_expr = true; - break; - case Expr_tkn_.Tid_paren_rhs: { - prv_prc = prc_stack.GetLast(); - while (prv_prc != null && prv_prc.Tid() != Expr_tkn_.Tid_paren_lhs) { - if (!prv_prc.Calc(ctx, this, val_stack)) return Null_rslt; - prc_stack.Pop(); - prv_prc = prc_stack.GetLast(); - } - if (prv_prc == Paren_bgn_tkn.Instance) - prc_stack.Pop(); - else - return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_closing_bracket); - mode_expr = false; + else // operator expected; fail b/c pi / e is not an operator; + return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_number); + } + if (mode_expr) { // NOTE: all the GetAlts have higher precedence; "break;" need to skip evaluation below else will fail for --1 + Func_tkn alt_prc = cur_prc.GetAlt(); + prc_stack.Push(alt_prc); break; } + prv_prc = prc_stack.Get_at_last(); + while (prv_prc != null && (cur_prc.Precedence() <= prv_prc.Precedence())) { + if (!prv_prc.Calc(ctx, this, val_stack)) return Null_rslt; + prc_stack.Pop(); + prv_prc = prc_stack.Get_at_last(); + } + prc_stack.Push(cur_prc); + mode_expr = true; + break; + case Expr_tkn_.Tid_paren_rhs: { + prv_prc = prc_stack.Get_at_last(); + while (prv_prc != null && prv_prc.Tid() != Expr_tkn_.Tid_paren_lhs) { + if (!prv_prc.Calc(ctx, this, val_stack)) return Null_rslt; + prc_stack.Pop(); + prv_prc = prc_stack.Get_at_last(); + } + if (prv_prc == Paren_bgn_tkn.Instance) + prc_stack.Pop(); + else + return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_closing_bracket); + mode_expr = false; + break; } } - if (cur_pos == src_len) break; - cur_byt = src[cur_pos]; } - while (prc_stack.Len() > 0) { - Func_tkn cur_prc = prc_stack.Pop(); - if (cur_prc.Tid() == Expr_tkn_.Tid_paren_lhs) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unclosed_bracket); - if (!cur_prc.Calc(ctx, this, val_stack)) return Null_rslt; - } - return val_stack.Len() == 0 ? Null_rslt : val_stack.Pop(); // HACK: for [[List of Premiers of South Australia by time in office]] and {{#expr:\n{{age in days + if (cur_pos == src_len) break; + cur_byt = src[cur_pos]; } + while (prc_stack.Len() > 0) { + Func_tkn cur_prc = prc_stack.Pop(); + if (cur_prc.Tid() == Expr_tkn_.Tid_paren_lhs) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unclosed_bracket); + if (!cur_prc.Calc(ctx, this, val_stack)) return Null_rslt; + } + return val_stack.Len() == 0 ? Null_rslt : val_stack.Pop(); // HACK: for [[List of Premiers of South Australia by time in office]] and {{#expr:\n{{age in days } - private static Btrie_fast_mgr expression_() { + + + public static final Decimal_adp Null_rslt = null; + private static Btrie_fast_mgr expression_() { // changed to instance; DATE:2016-07-20 Btrie_fast_mgr rv = Btrie_fast_mgr.ci_a7(); // NOTE:ci.ascii:MW_const.en; math and expressions Trie_add(rv, new Ws_tkn(Byte_ascii.Space)); Trie_add(rv, new Ws_tkn(Byte_ascii.Tab)); @@ -221,5 +221,5 @@ public class Pfunc_expr_shunter { return rv; } private static void Trie_add(Btrie_fast_mgr trie, Expr_tkn tkn) {trie.Add(tkn.Val_ary(), tkn);} - public static final Pfunc_expr_shunter Instance = new Pfunc_expr_shunter(); Pfunc_expr_shunter() {} + private static final byte[] Err_bgn_ary = Bry_.new_a7(""), Err_end_ary = Bry_.new_a7(""); } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifeq.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifeq.java index 2f40c4bfb..c527cbba9 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifeq.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifeq.java @@ -24,7 +24,7 @@ public class Pfunc_ifeq extends Pf_func_base { int self_args_len = self.Args_len(); if (self_args_len < 2) return; // no equal/not_equal clauses defined; return; EX: {{#if:a}} {{#if:a|b}} byte[] lhs = Eval_argx(ctx, src, caller, self); byte[] rhs = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 0); - if (Pf_func_.Eq_(lhs, rhs)) + if (Pf_func_.Eq(ctx, lhs, rhs)) bfr.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 1)); else bfr.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 2)); diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifeq_tst.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifeq_tst.java index 65f744458..c16adece8 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifeq_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifeq_tst.java @@ -18,7 +18,7 @@ along with this program. If not, see . package gplx.xowa.xtns.pfuncs.ifs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*; import org.junit.*; public class Pfunc_ifeq_tst { - private final Xop_fxt fxt = new Xop_fxt(); + private final Xop_fxt fxt = new Xop_fxt(); @Before public void init() {fxt.Reset();} @Test public void Ifeq_y() {fxt.Test_parse_tmpl_str_test("{{#ifeq:1|1|a|b}}" , "{{test}}" , "a");} diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexist_mgr.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexist_mgr.java index d4de12b4c..736de0793 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexist_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexist_mgr.java @@ -16,30 +16,32 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.xtns.pfuncs.ifs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*; -import gplx.core.envs.*; +import gplx.core.envs.*; import gplx.core.caches.*; import gplx.xowa.bldrs.wms.apis.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa.wikis.nss.*; public class Pfunc_ifexist_mgr { - private Xowd_page_itm db_page = Xowd_page_itm.new_tmp(); - private Hash_adp regy = Hash_adp_bry.cs(); - public void Clear() {regy.Clear();} + private final Xowd_page_itm db_page = Xowd_page_itm.new_tmp(); public boolean Exists(Xowe_wiki wiki, byte[] raw_bry) { if (Bry_.Len_eq_0(raw_bry)) return false; // return early; NOTE: {{autolink}} can pass in "" (see test) Xoa_ttl ttl = Xoa_ttl.Parse(wiki, raw_bry); if (ttl == null) return false; - byte[] ttl_bry = ttl.Page_db(); // NOTE: must use Page_db; EX: {{#ifexist:File:Peter & Paul fortress in SPB 03.jpg|y|n}} - Object exists_obj = regy.Get_by(ttl_bry); - if (exists_obj != null) return ((Pfunc_ifexist_itm)exists_obj).Exists(); - Pfunc_ifexist_itm exists_itm = new Pfunc_ifexist_itm(ttl_bry); - regy.Add(ttl_bry, exists_itm); + byte[] ttl_bry = ttl.Page_db(); // NOTE: must use Page_db; EX: {{#ifexist:File:Peter & Paul fortress in SPB 03.jpg|y|n}} + + // try to get from cache + Gfo_cache_mgr cache_mgr = wiki.Cache_mgr().Ifexist_cache(); + Pfunc_ifexist_itm cache_itm = (Pfunc_ifexist_itm)cache_mgr.Get_by_key(ttl_bry); + if (cache_itm != null) return cache_itm.Exists(); + + cache_itm = new Pfunc_ifexist_itm(ttl_bry); + cache_mgr.Add(ttl_bry, cache_itm, 1); db_page.Clear(); Xow_ns ttl_ns = ttl.Ns(); boolean rv = false; switch (ttl_ns.Id()) { case Xow_ns_.Tid__special: rv = true; break; // NOTE: some pages call for [[Special]]; always return true for now; DATE:2014-07-17 - case Xow_ns_.Tid__media: rv = Find_ttl_for_media_ns(exists_itm, wiki, ttl_ns, ttl_bry); break; - default: rv = Find_ttl_in_db(exists_itm, wiki, ttl_ns, ttl_bry); break; + case Xow_ns_.Tid__media: rv = Find_ttl_for_media_ns(cache_itm, wiki, ttl_ns, ttl_bry); break; + default: rv = Find_ttl_in_db(cache_itm, wiki, ttl_ns, ttl_bry); break; } - exists_itm.Exists_(rv); + cache_itm.Exists_(rv); return rv; } private boolean Find_ttl_in_db(Pfunc_ifexist_itm itm, Xowe_wiki wiki, Xow_ns ns, byte[] ttl_bry) { @@ -73,8 +75,9 @@ public class Pfunc_ifexist_mgr { } } } -class Pfunc_ifexist_itm { +class Pfunc_ifexist_itm implements Rls_able { public Pfunc_ifexist_itm(byte[] ttl) {this.ttl = ttl;} public byte[] Ttl() {return ttl;} private byte[] ttl; public boolean Exists() {return exists;} public void Exists_(boolean v) {exists = v;} private boolean exists; + public void Rls() {} } \ No newline at end of file diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexist_tst.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexist_tst.java index 2cab27322..41134faea 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexist_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexist_tst.java @@ -21,7 +21,7 @@ public class Pfunc_ifexist_tst { private final Xop_fxt fxt = new Xop_fxt(); @Before public void init() { fxt.Reset(); - fxt.Wiki().Parser_mgr().Ifexist_mgr().Clear(); + fxt.Wiki().Cache_mgr().Ifexist_cache().Clear(); } @Test public void Basic_pass() {fxt.Test_parse_tmpl_str_test("{{#ifexist: Abc | exists | doesn't exist }}" , "{{test}}" , "doesn't exist");} @Test public void Empty() {fxt.Test_parse_tmpl_str_test("{{#ifexist:|y|n}}" , "{{test}}" , "n");} // NOTE: {{autolink}} can pass in "" diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexpr.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexpr.java index daaa4ec33..f8ce1467a 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexpr.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_ifexpr.java @@ -26,6 +26,7 @@ public class Pfunc_ifexpr extends Pf_func_base { @Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) { int self_args_len = self.Args_len(); byte[] argx = Eval_argx(ctx, src, caller, self); if (argx == null) return; + Pfunc_expr_shunter shunter = ctx.Tmp_mgr().Expr_shunter(); Decimal_adp result = shunter.Evaluate(ctx, argx); boolean is_nan = result == Pfunc_expr_shunter.Null_rslt; if (is_nan && shunter.Err().Len() > 0) { @@ -39,5 +40,4 @@ public class Pfunc_ifexpr extends Pf_func_base { bfr.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 0)); } } - private final Pfunc_expr_shunter shunter = Pfunc_expr_shunter.Instance; } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_switch.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_switch.java index 3f4b88e5c..7a2290246 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_switch.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ifs/Pfunc_switch.java @@ -38,7 +38,7 @@ public class Pfunc_switch extends Pf_func_base { last_keyless_arg = null; // set last_keyless_arg to null byte[] case_key = Get_or_eval(ctx, src, caller, self, bfr, arg.Key_tkn(), tmp); if ( fall_thru_found // fall-thru found earlier; take cur value; EX: {{#switch:a|a|b=1|c=2}} -> 1 - || Pf_func_.Eq_(case_key, argx) // case_key matches argx; EX: {{#switch:a|a=1}} + || Pf_func_.Eq(ctx, case_key, argx) // case_key matches argx; EX: {{#switch:a|a=1}} ) { match = Get_or_eval(ctx, src, caller, self, bfr, arg.Val_tkn(), tmp); break; // stop iterating; explicit match found; @@ -52,7 +52,7 @@ public class Pfunc_switch extends Pf_func_base { else { // = missing; EX: "|a|", "|#default|" last_keyless_arg = arg; byte[] case_val = Get_or_eval(ctx, src, caller, self, bfr, arg.Val_tkn(), tmp); - if (Pf_func_.Eq_(case_val, argx)) // argx matches case_val; EX: case_val="|a|" and argx="a" + if (Pf_func_.Eq(ctx, case_val, argx)) // argx matches case_val; EX: case_val="|a|" and argx="a" fall_thru_found = true; // set as fall-thru; note that fall-thrus will have "val" in next keyed arg, so need to continue iterating; EX: {{#switch:a|a|b=1|c=2}} "a" is fall-thru, but "b" is next keyed arg with a val else if (kwd_mgr.Kwd_default_match(case_val)) { // case_val starts with #default; EX: "|#default|" or "|#defaultabc|" last_keyless_arg = null; // unflag last keyless arg else |#defaultabc| will be treated as last_keyless_arg and generate "#defaultabc"; DATE:2014-05-29 diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_plural.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_plural.java index 1c4f15eda..6295a96a1 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_plural.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_plural.java @@ -23,11 +23,11 @@ public class Pfunc_plural extends Pf_func_base { @Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {// REF.MW: CoreParserFunctions.php byte[] number = Eval_argx(ctx, src, caller, self); int self_args_len = self.Args_len(); - int arg_idx = Pf_func_.Eq_(number, Ary_Num_1) ? 0 : 1; + int arg_idx = Pf_func_.Eq(ctx, number, Ary_Num_1) ? 0 : 1; if (arg_idx == 1 && self_args_len == 1) arg_idx = 0; // number is plural, but plural_arg not present; use singular; see test byte[] word = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, arg_idx); bfr.Add(word); - } static final byte[] Ary_Num_1 = new byte[] {Byte_ascii.Num_1}; + } static final byte[] Ary_Num_1 = new byte[] {Byte_ascii.Num_1}; @Override public int Id() {return Xol_kwd_grp_.Id_i18n_plural;} @Override public Pf_func New(int id, byte[] name) {return new Pfunc_plural().Name_(name);} } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/scribunto/Pfunc_scrib_lib.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/scribunto/Pfunc_scrib_lib.java index 4df444a77..cdc8b8f92 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/scribunto/Pfunc_scrib_lib.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/scribunto/Pfunc_scrib_lib.java @@ -23,6 +23,7 @@ public class Pfunc_scrib_lib implements Scrib_lib { 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 Pfunc_scrib_lib();} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { this.core = core; Init(); diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_case.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_case.java index 11541caf2..8a90a3541 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_case.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_case.java @@ -30,7 +30,7 @@ public class Pfunc_case extends Pf_func_base { // EX: {{lc:A}} -> a Xol_lang_itm lang = ctx.Wiki().Lang(); boolean upper = case_type == Xol_lang_itm.Tid_upper; if (first) { - Bry_bfr tmp_bfr = ctx.App().Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512(); argx = lang.Case_mgr().Case_build_1st(tmp_bfr, upper, argx, 0, argx_len); tmp_bfr.Mkr_rls(); } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag.java index e0272332f..67506ba77 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag.java @@ -24,7 +24,7 @@ public class Pfunc_tag extends Pf_func_base { @Override public boolean Func_require_colon_arg() {return true;} @Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) { // make based on {{#tag}}; EX: {{#tag:ref|a|name=1}} -> a - Bry_bfr tmp_bfr = ctx.App().Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512(); try { // get tag_idx, tag_data, and tag_is_ref int tag_idx = -1; diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_fmt_itm_.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_fmt_itm_.java index 9d4e9cc11..02ce72b28 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_fmt_itm_.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_fmt_itm_.java @@ -163,56 +163,56 @@ public class Pft_fmt_itm_ { .Add("xmY" , Pft_fmt_itm_.Hijiri_year_idx) // TODO_OLD: space; " ; + public static Pft_fmt_itm[] Parse(Xop_ctx ctx, byte[] fmt) { - synchronized (fmt_itms) { // LOCK:static-obj; DATE:2016-07-06 - Btrie_fast_mgr trie = Pft_fmt_itm_.Regy; - Btrie_rv trv = new Btrie_rv(); - int i = 0, fmt_len = fmt.length; - fmt_itms.Clear(); int raw_bgn = String_.Pos_neg1; byte raw_byt = Byte_.Zero; - while (i < fmt_len) { - byte b = fmt[i]; - Object o = trie.Match_at_w_b0(trv, b, fmt, i, fmt_len); - if (o != null) { - if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;} - fmt_itms.Add((Pft_fmt_itm)o); - i = trv.Pos(); - } - else { - switch (b) { - case Byte_ascii.Backslash: - if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;} - ++i; // peek next char - if (i == fmt_len) // trailing backslash; add one; EX: "b\" -> "b\" not "b" - fmt_itms.Add(new Pft_fmt_itm_raw_byt(Byte_ascii.Backslash)); - else - fmt_itms.Add(new Pft_fmt_itm_raw_byt(fmt[i])); - ++i; - break; - case Byte_ascii.Quote: - if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;} - ++i; // skip quote_bgn - raw_bgn = i; - while (i < fmt_len) { - b = fmt[i]; - if (b == Byte_ascii.Quote) { - break; - } - else - ++i; + List_adp fmt_itms = ctx.Wiki().Parser_mgr().Time_parser_itms(); + Btrie_fast_mgr trie = Pft_fmt_itm_.Regy; + Btrie_rv trv = new Btrie_rv(); + int i = 0, fmt_len = fmt.length; + fmt_itms.Clear(); int raw_bgn = String_.Pos_neg1; byte raw_byt = Byte_.Zero; + while (i < fmt_len) { + byte b = fmt[i]; + Object o = trie.Match_at_w_b0(trv, b, fmt, i, fmt_len); + if (o != null) { + if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;} + fmt_itms.Add((Pft_fmt_itm)o); + i = trv.Pos(); + } + else { + switch (b) { + case Byte_ascii.Backslash: + if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;} + ++i; // peek next char + if (i == fmt_len) // trailing backslash; add one; EX: "b\" -> "b\" not "b" + fmt_itms.Add(new Pft_fmt_itm_raw_byt(Byte_ascii.Backslash)); + else + fmt_itms.Add(new Pft_fmt_itm_raw_byt(fmt[i])); + ++i; + break; + case Byte_ascii.Quote: + if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;} + ++i; // skip quote_bgn + raw_bgn = i; + while (i < fmt_len) { + b = fmt[i]; + if (b == Byte_ascii.Quote) { + break; } - fmt_itms.Add(i - raw_bgn == 0 ? new Pft_fmt_itm_raw_byt(Byte_ascii.Quote) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); - raw_bgn = String_.Pos_neg1; - ++i; // skip quote_end - break; - default: - if (raw_bgn == String_.Pos_neg1) {raw_bgn = i; raw_byt = b;} - i += gplx.core.intls.Utf8_.Len_of_char_by_1st_byte(b); - break; - } + else + ++i; + } + fmt_itms.Add(i - raw_bgn == 0 ? new Pft_fmt_itm_raw_byt(Byte_ascii.Quote) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); + raw_bgn = String_.Pos_neg1; + ++i; // skip quote_end + break; + default: + if (raw_bgn == String_.Pos_neg1) {raw_bgn = i; raw_byt = b;} + i += gplx.core.intls.Utf8_.Len_of_char_by_1st_byte(b); + break; } } - if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(fmt_len - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(fmt[fmt_len - 1]) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, fmt_len)); raw_bgn = String_.Pos_neg1;} - return (Pft_fmt_itm[])fmt_itms.To_ary(Pft_fmt_itm.class); } - } private static List_adp fmt_itms = List_adp_.New(); + if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(fmt_len - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(fmt[fmt_len - 1]) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, fmt_len)); raw_bgn = String_.Pos_neg1;} + return (Pft_fmt_itm[])fmt_itms.To_ary(Pft_fmt_itm.class); + } } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_date_int.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_date_int.java index bf3a10dc4..eb3585159 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_date_int.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_date_int.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*; import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*; -import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; +import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.xtns.pfuncs.times.*; public class Pft_func_date_int extends Pf_func_base { public Pft_func_date_int(int id, int date_tid) {this.id = id; this.date_tid = date_tid;} private int date_tid; @Override public int Id() {return id;} private int id; @@ -25,6 +25,7 @@ public class Pft_func_date_int extends Pf_func_base { @Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) { DateAdp date = DateAdp_.MinValue; Xowe_wiki wiki = ctx.Wiki(); Xol_lang_itm lang = ctx.Lang(); + Pft_func_formatdate_bldr date_fmt_bldr = wiki.Parser_mgr().Date_fmt_bldr(); switch (date_tid) { case Date_tid_lcl: date = DateAdp_.Now(); break; case Date_tid_utc: date = DateAdp_.Now().XtoUtc(); break; @@ -35,39 +36,39 @@ public class Pft_func_date_int extends Pf_func_base { case Xol_kwd_grp_.Id_utc_year: case Xol_kwd_grp_.Id_lcl_year: case Xol_kwd_grp_.Id_rev_year: - Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Year_len4); + date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Year_len4); break; case Xol_kwd_grp_.Id_utc_month_int_len2: case Xol_kwd_grp_.Id_lcl_month_int_len2: case Xol_kwd_grp_.Id_rev_month_int_len2: - Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Month_int_len2); + date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Month_int_len2); break; case Xol_kwd_grp_.Id_utc_month_int: case Xol_kwd_grp_.Id_lcl_month_int: case Xol_kwd_grp_.Id_rev_month_int: - Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Month_int); + date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Month_int); break; case Xol_kwd_grp_.Id_utc_day_int_len2: case Xol_kwd_grp_.Id_lcl_day_int_len2: case Xol_kwd_grp_.Id_rev_day_int_len2: - Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Day_int_len2); + date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Day_int_len2); break; case Xol_kwd_grp_.Id_utc_day_int: case Xol_kwd_grp_.Id_lcl_day_int: case Xol_kwd_grp_.Id_rev_day_int: - Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Day_int); + date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Day_int); break; case Xol_kwd_grp_.Id_lcl_hour: case Xol_kwd_grp_.Id_utc_hour: - Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Hour_base24_len2); + date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Hour_base24_len2); break; case Xol_kwd_grp_.Id_lcl_dow: case Xol_kwd_grp_.Id_utc_dow: - Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Dow_base1_int); + date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Dow_base1_int); break; case Xol_kwd_grp_.Id_lcl_week: case Xol_kwd_grp_.Id_utc_week: - Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.WeekOfYear_int); + date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.WeekOfYear_int); break; case Xol_kwd_grp_.Id_lcl_time: case Xol_kwd_grp_.Id_utc_time: // 17:29 diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_formatdate.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_formatdate.java index 743c543f5..672fd8ad4 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_formatdate.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_formatdate.java @@ -35,13 +35,12 @@ public class Pft_func_formatdate extends Pf_func_base { bfr.Add(date_bry); return; } - DateAdp date = Pft_func_time.ParseDate(date_bry, false, ctx.App().Utl__bfr_mkr().Get_b512().Mkr_rls()); + DateAdp date = Pft_func_time.ParseDate(date_bry, false, ctx.Wiki().Utl__bfr_mkr().Get_b512().Mkr_rls()); if (date == null) {bfr.Add(date_bry); return;} // date not parseable; return self; DATE:2014-04-13 - date_bldr.Format(bfr, ctx.Wiki(), ctx.Lang(), date, (Pft_fmt_itm[])o); + ctx.Wiki().Parser_mgr().Date_fmt_bldr().Format(bfr, ctx.Wiki(), ctx.Lang(), date, (Pft_fmt_itm[])o); } - public static Pft_func_formatdate_bldr Date_bldr() {return date_bldr;} private static Pft_func_formatdate_bldr date_bldr = new Pft_func_formatdate_bldr(); - private static final Pft_fmt_itm[] Fmt_itms_default = new Pft_fmt_itm[0]; - private static final Btrie_fast_mgr trie = Btrie_fast_mgr.cs() + private static final Pft_fmt_itm[] Fmt_itms_default = new Pft_fmt_itm[0]; + private static final Btrie_fast_mgr trie = Btrie_fast_mgr.cs() .Add("dmy" , new Pft_fmt_itm[] {Pft_fmt_itm_.Day_int, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Month_name, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Year_len4}) .Add("mdy" , new Pft_fmt_itm[] {Pft_fmt_itm_.Month_name, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Day_int, Pft_fmt_itm_.Byte_comma, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Year_len4}) .Add("ymd" , new Pft_fmt_itm[] {Pft_fmt_itm_.Year_len4, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Month_name, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Day_int}) diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_formatdate_bldr.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_formatdate_bldr.java index 78d25c561..9854a6c1f 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_formatdate_bldr.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_formatdate_bldr.java @@ -22,46 +22,42 @@ public class Pft_func_formatdate_bldr { public Pft_func_formatdate_bldr Idx_nxt_(int v) {idx_nxt = v; return this;} private int idx_nxt; public Pft_fmt_itm[] Fmt_itms() {return fmt_itms;} private Pft_fmt_itm[] fmt_itms; public void Format(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang_itm lang, DateAdp date, Pft_fmt_itm fmt_itm) { - synchronized (this) { // LOCK:static-obj;Pft_func_formatdate.Date_bldr(); DATE:2016-07-07 - fmt_itm.Fmt(bfr, wiki, lang, date, this); - } + fmt_itm.Fmt(bfr, wiki, lang, date, this); } public void Format(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang_itm lang, DateAdp date, Pft_fmt_itm[] fmt_itms) { - synchronized (this) { // LOCK:static-obj;Pft_func_formatdate.Date_bldr(); DATE:2016-07-07 - this.fmt_itms = fmt_itms; - int len = fmt_itms.length; - idx_cur = 0; idx_nxt = -1; - Pft_fmt_itm chained_fmt = null; - while (idx_cur < len) { - Pft_fmt_itm fmt_itm = fmt_itms[idx_cur]; - if (fmt_itm.TypeId() == Pft_fmt_itm_.Tid_hebrew_numeral) - chained_fmt = fmt_itm; - else { - if (chained_fmt != null) { - Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_b128(); - synchronized (tmp_bfr) { - fmt_itm.Fmt(tmp_bfr, wiki, lang, date, this); - chained_fmt.Fmt(tmp_bfr, wiki, lang, date, this); - bfr.Add(tmp_bfr.To_bry_and_rls()); - chained_fmt = null; - } + this.fmt_itms = fmt_itms; + int len = fmt_itms.length; + idx_cur = 0; idx_nxt = -1; + Pft_fmt_itm chained_fmt = null; + while (idx_cur < len) { + Pft_fmt_itm fmt_itm = fmt_itms[idx_cur]; + if (fmt_itm.TypeId() == Pft_fmt_itm_.Tid_hebrew_numeral) + chained_fmt = fmt_itm; + else { + if (chained_fmt != null) { + Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_b128(); + synchronized (tmp_bfr) { + fmt_itm.Fmt(tmp_bfr, wiki, lang, date, this); + chained_fmt.Fmt(tmp_bfr, wiki, lang, date, this); + bfr.Add(tmp_bfr.To_bry_and_rls()); + chained_fmt = null; } - else - fmt_itm.Fmt(bfr, wiki, lang, date, this); - } - if (idx_nxt == -1) - ++idx_cur; - else { - idx_cur = idx_nxt; - idx_nxt = -1; } + else + fmt_itm.Fmt(bfr, wiki, lang, date, this); } - if (chained_fmt != null) { - int year_int = bfr.To_int_and_clear(-1); - if (year_int != -1) { // handle no format; EX:{{#time:xh}} DATE:2014-07-20 - date = DateAdp_.seg_(new int[] {year_int, date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), date.Frac()}); - chained_fmt.Fmt(bfr, wiki, lang, date, this); - } + if (idx_nxt == -1) + ++idx_cur; + else { + idx_cur = idx_nxt; + idx_nxt = -1; + } + } + if (chained_fmt != null) { + int year_int = bfr.To_int_and_clear(-1); + if (year_int != -1) { // handle no format; EX:{{#time:xh}} DATE:2014-07-20 + date = DateAdp_.seg_(new int[] {year_int, date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), date.Frac()}); + chained_fmt.Fmt(bfr, wiki, lang, date, this); } } } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_time.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_time.java index 9ddde5c25..7b7ad2dd6 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_time.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_time.java @@ -30,6 +30,7 @@ public class Pft_func_time extends Pf_func_base { byte[] arg_lang = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 1); Bry_bfr error_bfr = Bry_bfr_.New(); DateAdp date = ParseDate(arg_date, utc, error_bfr); + Xowe_wiki wiki = ctx.Wiki(); if (date == null || error_bfr.Len() > 0) bfr.Add_str_a7("").Add_bfr_and_clear(error_bfr).Add_str_a7(""); else { @@ -37,11 +38,11 @@ public class Pft_func_time extends Pf_func_base { if (Bry_.Len_gt_0(arg_lang)) { Xol_lang_stub specified_lang_itm = Xol_lang_stub_.Get_by_key_or_null(arg_lang); if (specified_lang_itm != null) { // NOTE: if lang_code is bad, then ignore (EX:bad_code) - Xol_lang_itm specified_lang = ctx.Wiki().Appe().Lang_mgr().Get_by_or_new(arg_lang); + Xol_lang_itm specified_lang = wiki.Appe().Lang_mgr().Get_by_or_new(arg_lang); lang = specified_lang; } } - Pft_func_formatdate.Date_bldr().Format(bfr, ctx.Wiki(), lang, date, fmt_ary); + wiki.Parser_mgr().Date_fmt_bldr().Format(bfr, wiki, lang, date, fmt_ary); } } public static DateAdp ParseDate(byte[] date, boolean utc, Bry_bfr error_bfr) { diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_parser.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_parser.java index 6801eabad..55f94549e 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_parser.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_parser.java @@ -45,10 +45,8 @@ class Pxd_parser { fmtr.Bld_bfr(error_bfr, args); } private Bry_bfr error_bfr = Bry_bfr_.New_w_size(32); public DateAdp Parse(byte[] src, Bry_bfr error_bfr) { -// synchronized (this) { // LOCK:static-obj; DATE:2016-07-06 - Tokenize(src); // NOTE: should check if Tokenize failed, but want to be liberal as date parser is not fully implemented; this will always default to 1st day of year; DATE:2014-03-27 - return Evaluate(src, error_bfr); -// } + Tokenize(src); // NOTE: should check if Tokenize failed, but want to be liberal as date parser is not fully implemented; this will always default to 1st day of year; DATE:2014-03-27 + return Evaluate(src, error_bfr); } private boolean Tokenize(byte[] src) { this.src = src; src_len = src.length; diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_anchorencode.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_anchorencode.java index cfee4d74a..b21ab9229 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_anchorencode.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_anchorencode.java @@ -35,7 +35,7 @@ public class Pfunc_anchorencode extends Pf_func_base { // EX: {{anchorencode:a b @Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) { if (anchor_ctx == null) Func_init(ctx); byte[] val_ary = Eval_argx(ctx, src, caller, self); if (val_ary == Bry_.Empty) return; - Anchor_encode(val_ary, bfr, ctx.App().Utl__bfr_mkr().Get_b512().Mkr_rls()); + Anchor_encode(val_ary, bfr, ctx.Wiki().Utl__bfr_mkr().Get_b512().Mkr_rls()); } public static void Anchor_encode(byte[] src, Bry_bfr bfr, Bry_bfr tmp_bfr) { Xop_root_tkn root = anchor_ctx.Tkn_mkr().Root(src); diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_filepath.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_filepath.java index 535a5268c..45ae41b58 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_filepath.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_filepath.java @@ -16,39 +16,40 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*; -import gplx.core.envs.*; +import gplx.core.envs.*; import gplx.core.caches.*; import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*; import gplx.xowa.wikis.nss.*; -import gplx.xowa.files.*; import gplx.xowa.files.repos.*; -import gplx.xowa.files.origs.*; +import gplx.xowa.files.*; import gplx.xowa.files.repos.*; import gplx.xowa.files.origs.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; public class Pfunc_filepath extends Pf_func_base { @Override public boolean Func_require_colon_arg() {return true;} @Override public int Id() {return Xol_kwd_grp_.Id_url_filepath;} @Override public Pf_func New(int id, byte[] name) {return new Pfunc_filepath().Name_(name);} @Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) { + // init byte[] val_ary = Eval_argx(ctx, src, caller, self); if (val_ary == Bry_.Empty) return; Xowe_wiki wiki = ctx.Wiki(); Xoa_ttl ttl = wiki.Ttl_parse(Xow_ns_.Tid__file, val_ary); if (ttl == null) return; // text is not valid ttl; exit; - Xoae_page page = Load_page(wiki, ttl); if (page.Db().Page().Exists_n()) return; // page not found in wiki or commons; exit; - byte[] ttl_bry = page.Ttl().Page_url(); - -// Xof_orig_itm orig_itm = wiki.File_mgr().Orig_mgr().Find_by_ttl_or_null(ttl_bry); -// if (orig_itm == Xof_orig_itm.Null) return; -// Xof_repo_itm repo = wiki.File_mgr().Repo_mgr().Get_trg_by_id_or_null(orig_itm.Repo()).Trg(); -// url_bldr.Init_for_trg_html(Xof_repo_itm_.Mode_orig, repo, orig_itm.Ttl(), Xof_file_wkr_.Md5_fast(orig_itm.Ttl()), orig_itm.Ext(), -1, -1, -1); -// bfr.Add(url_bldr.Xto_bry()); + Pfunc_filepath_itm commons_itm = Load_page(wiki, ttl); if (!commons_itm.Exists()) return; // page not found in wiki or commons; exit; + byte[] ttl_bry = commons_itm.Page_url(); + // look for file Xofw_file_finder_rslt tmp_rslt = wiki.File_mgr().Repo_mgr().Page_finder_locate(ttl_bry); if (tmp_rslt.Repo_idx() == Byte_.Max_value_127) return; Xof_repo_itm trg_repo = wiki.File_mgr().Repo_mgr().Repos_get_at(tmp_rslt.Repo_idx()).Trg(); + Xof_xfer_itm xfer_itm = ctx.Tmp_mgr().Xfer_itm(); xfer_itm.Orig_ttl_and_redirect_(ttl_bry, Bry_.Empty); // redirect is empty b/c Get_page does all redirect lookups - byte[] url = url_bldr.Init_for_trg_html(Xof_repo_itm_.Mode_orig, trg_repo, ttl_bry, xfer_itm.Orig_ttl_md5(), xfer_itm.Orig_ext(), Xof_img_size.Size__neg1, Xof_lnki_time.Null, Xof_lnki_page.Null).Xto_bry(); + byte[] url = wiki.Parser_mgr().Url_bldr().Init_for_trg_html(Xof_repo_itm_.Mode_orig, trg_repo, ttl_bry, xfer_itm.Orig_ttl_md5(), xfer_itm.Orig_ext(), Xof_img_size.Size__neg1, Xof_lnki_time.Null, Xof_lnki_page.Null).Xto_bry(); bfr.Add(url); } - private static final Xof_xfer_itm xfer_itm = new Xof_xfer_itm(); - private static final Xof_url_bldr url_bldr = new Xof_url_bldr(); - private static Xoae_page Load_page(Xowe_wiki wiki, Xoa_ttl ttl) { + private static Pfunc_filepath_itm Load_page(Xowe_wiki wiki, Xoa_ttl ttl) { + // try to get from cache + Gfo_cache_mgr cache_mgr = wiki.Cache_mgr().Commons_cache(); + byte[] cache_key = ttl.Page_url(); + Pfunc_filepath_itm cache_itm = (Pfunc_filepath_itm)cache_mgr.Get_by_key(cache_key); + if (cache_itm != null) return cache_itm; + + // do db retrieval Xoae_page page = wiki.Data_mgr().Load_page_by_ttl(ttl); if (page.Db().Page().Exists_n()) { // file not found in current wiki; try commons; Xowe_wiki commons_wiki = (Xowe_wiki)wiki.Appe().Wiki_mgr().Get_by_or_null(wiki.Commons_wiki_key()); @@ -61,6 +62,16 @@ public class Pfunc_filepath extends Pf_func_base { page = commons_wiki.Data_mgr().Load_page_by_ttl(ttl); } } - return page; + + // add to cache + cache_itm = new Pfunc_filepath_itm(page.Db().Page().Exists(), cache_key); + cache_mgr.Add(cache_key, cache_itm, 1); + return cache_itm; } } +class Pfunc_filepath_itm implements Rls_able { + public Pfunc_filepath_itm(boolean exists, byte[] page_url) {this.exists = exists; this.page_url = page_url;} + public boolean Exists() {return exists;} private final boolean exists; + public byte[] Page_url() {return page_url;} private final byte[] page_url; + public void Rls() {} +} diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java index a3b63e0ac..c94df8abc 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java @@ -34,7 +34,7 @@ public class Pfunc_rel2abs extends Pf_func_base { byte[] qry = Eval_argx(ctx, src, caller, self); byte[] orig = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self.Args_len(), 0); if (orig.length == 0) orig = ctx.Page().Ttl().Full_txt_w_ttl_case(); - bfr.Add(Rel2abs(ctx.App().Utl__bfr_mkr().Get_b512().Mkr_rls(), qry, orig)); + bfr.Add(Rel2abs(ctx.Wiki().Utl__bfr_mkr().Get_b512().Mkr_rls(), qry, orig)); } public static boolean Rel2abs_ttl(byte[] ttl, int bgn, int end) { int last = end - 1; diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_urlfunc.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_urlfunc.java index 64ef23ab8..9e7c78c8f 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_urlfunc.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_urlfunc.java @@ -42,7 +42,7 @@ public class Pfunc_urlfunc extends Pf_func_base { // EX: {{lc:A}} -> a .Add_mid(ttl_ary, xwiki.Key_bry().length + 1, ttl_ary.length); // "A#b?c=d"; +1 for colon after "commons:"; NOTE: ugly way of getting rest of url, but ttl currently does not have Full_wo_wiki } else { - Bry_bfr tmp_bfr = ctx.App().Utl__bfr_mkr().Get_b512().Mkr_rls(); + Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512().Mkr_rls(); switch (tid) { case Tid_local: tmp_bfr.Add(ctx.Wiki().Props().ArticlePath());break; case Tid_full: tmp_bfr.Add(Bry_relative_url).Add(ctx.Wiki().Props().Server_name()).Add(ctx.Wiki().Props().ArticlePath()); break; diff --git a/400_xowa/src/gplx/xowa/xtns/proofreadPage/Pp_pages_nde.java b/400_xowa/src/gplx/xowa/xtns/proofreadPage/Pp_pages_nde.java index b67162677..21bd91797 100644 --- a/400_xowa/src/gplx/xowa/xtns/proofreadPage/Pp_pages_nde.java +++ b/400_xowa/src/gplx/xowa/xtns/proofreadPage/Pp_pages_nde.java @@ -62,7 +62,7 @@ public class Pp_pages_nde implements Xox_xnde, Mwh_atr_itm_owner1 { Xoae_page page = ctx.Page(); if (page.Pages_recursed()) return; // moved from Pp_index_parser; DATE:2014-05-21s page.Pages_recursed_(true); - Bry_bfr full_bfr = app.Utl__bfr_mkr().Get_m001(); + Bry_bfr full_bfr = wiki.Utl__bfr_mkr().Get_m001(); Hash_adp_bry lst_page_regy = ctx.Lst_page_regy(); if (lst_page_regy == null) lst_page_regy = Hash_adp_bry.cs(); // SEE:NOTE:page_regy; DATE:2014-01-01 page.Html_data().Indicators().Enabled_(Bool_.N); // disable b/c should not add to current page; PAGE:en.s:The_Parochial_System_(Wilberforce,_1838); DATE:2015-04-29 byte[] page_bry = Bld_wikitext(full_bfr, lst_page_regy); @@ -300,7 +300,7 @@ public class Pp_pages_nde implements Xox_xnde, Mwh_atr_itm_owner1 { int list_len = list.Count(); if (list_len == 0) return Ttls_null; Xoa_ttl[] rv = new Xoa_ttl[(list_len / step_int) + ((list_len % step_int == 0) ? 0 : 1)]; int rv_idx = 0; - Bry_bfr ttl_bfr = app.Utl__bfr_mkr().Get_b512(); + Bry_bfr ttl_bfr = wiki.Utl__bfr_mkr().Get_b512(); for (int i = 0; i < list_len; i += step_int) { Int_obj_val page = (Int_obj_val)list.Get_at(i); ttl_bfr.Add(ns_page.Name_db_w_colon()) // EX: 'Page:' @@ -329,7 +329,7 @@ public class Pp_pages_nde implements Xox_xnde, Mwh_atr_itm_owner1 { Xoa_ttl bgn_page_ttl = bgn_page_bry == null ? null : ary[0]; Xoa_ttl end_page_ttl = end_page_bry == null ? null : ary[ary_len - 1]; - Bry_bfr page_bfr = app.Utl__bfr_mkr().Get_m001(); + Bry_bfr page_bfr = wiki.Utl__bfr_mkr().Get_m001(); ctx.Tmpl_output_(page_bfr); Lst_pfunc_wkr lst_pfunc_wkr = new Lst_pfunc_wkr(); for (int i = 0; i < ary_len; i++) { 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 2a90ddbd2..55aa867d3 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core.java @@ -22,6 +22,7 @@ import gplx.xowa.xtns.scribunto.libs.*; import gplx.xowa.xtns.scribunto.engines. import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; public class Scrib_core { private Hash_adp_bry mods = Hash_adp_bry.cs(); + private int expensive_function_count; public Scrib_core(Xoae_app app, Xop_ctx ctx) {// NOTE: ctx needed for language reg this.app = app; this.ctx = ctx; this.wiki = ctx.Wiki(); this.page = ctx.Page(); // NOTE: wiki / page needed for title reg; DATE:2014-02-05 @@ -114,7 +115,7 @@ public class Scrib_core { public void Increment_expensive_function_count() { ++expensive_function_count; if (expensive_function_count > 255) {} - } private int expensive_function_count; + } public Scrib_lua_mod RegisterInterface(Scrib_lib lib, Io_url url, Keyval... args) { this.RegisterLibrary(lib.Procs()); Scrib_lua_mod rv = this.LoadLibraryFromFile(url.NameAndExt(), Io_mgr.Instance.LoadFilStr(url)); diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core_fxt.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core_fxt.java index 15c639b2a..d3fe669e6 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core_fxt.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_core_fxt.java @@ -22,7 +22,7 @@ public class Scrib_core_fxt { public Scrib_core_fxt(Xop_fxt fxt) { app = fxt.App(); wiki = fxt.Wiki(); - core = wiki.Parser_mgr().Scrib().Core_make(wiki.Parser_mgr().Ctx()); + core = wiki.Parser_mgr().Scrib().Core_init(wiki.Parser_mgr().Ctx()); server = new Process_server_mock(); core.Interpreter().Server_(server); } @@ -30,7 +30,7 @@ public class Scrib_core_fxt { if (core == null) { app = Xoa_app_fxt.Make__app__edit(); wiki = Xoa_app_fxt.Make__wiki__edit(app); - core = wiki.Parser_mgr().Scrib().Core_make(wiki.Parser_mgr().Ctx()); + core = wiki.Parser_mgr().Scrib().Core_init(wiki.Parser_mgr().Ctx()); server = new Process_server_mock(); core.Interpreter().Server_(server); } 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 e33374c30..8c0872c3d 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 @@ -16,49 +16,39 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.xtns.scribunto; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; +import gplx.xowa.wikis.*; import gplx.xowa.parsers.*; public class Scrib_core_mgr { - private static final List_adp cores = List_adp_.New(); public Scrib_core Core() {return core;} private Scrib_core core; - public Scrib_core Core_make(Xop_ctx ctx) { + public void Terminate_when_page_changes_y_() {terminate_when_page_changes = true;} private boolean terminate_when_page_changes; + public Scrib_core Core_init(Xop_ctx ctx) { core = new Scrib_core(ctx.App(), ctx); - core_invalidate_when_page_changes = false; - synchronized (cores) { - cores.Add(core); - } + terminate_when_page_changes = false; return core; } public void Core_term() { - if (core != null) core.Term(); - synchronized (cores) { - cores.Del(core); + if (core != null) { + core.Term(); + core = null; } - core = null; } - public void Core_invalidate_when_page_changes() {core_invalidate_when_page_changes = true;} private boolean core_invalidate_when_page_changes; - public void Core_page_changed(Xoae_page page) { - if ( core != null // core explicitly invalidated - || core_invalidate_when_page_changes // core marked invalidated b/c of error in {{#invoke}} but won't be regen'd until page changes; invalidate now; PAGE:th.d:all; DATE:2014-10-03 - ) { - if ( core != null // null check - && Bry_.Eq(page.Wiki().Domain_bry(), core.Cur_wiki()) // current page is in same wiki as last page - && !core_invalidate_when_page_changes // if core_invalidate_when_page_changes, then must call Core_term - ) - core.When_page_changed(page); - else // current page is in different wiki - Core_term(); // invalidate scrib engine; note that lua will cache chunks by Module name and two modules in two different wikis can have the same name, but different data: EX:Module:Citation/CS1/Configuration and enwiki / zhwiki; DATE:2014-03-21 - core_invalidate_when_page_changes = false; + public void When_page_changed(Xoae_page page) { + if (terminate_when_page_changes) { // true when error in {{#invoke}}; PAGE:th.d:all; DATE:2014-10-03 + Core_term(); // terminate core; note that next call to {{#invoke}} will check for null and rebuild if null; + terminate_when_page_changes = false; + } + else { // no error on previous page; notify core that page changed; note that lua will cache chunks by Module name and two modules in two different wikis can have the same name, but different data: EX:Module:Citation/CS1/Configuration and enwiki / zhwiki; DATE:2014-03-21 + if (core != null) // null-check needed when engine first created + core.When_page_changed(page); // NOTE: must call When_page_changed on core to update page; else, current ttl is not updated, and scrib_wikibase will return wrong document; DATE:2016-07-22 } } - public static void Term_all() { - synchronized (cores) { - int cores_len = cores.Len(); - for (int i = 0; i < cores_len; ++i) { - Scrib_core core = (Scrib_core)cores.Get_at(i); - core.Term(); - } - cores.Clear(); + public static void Term_all(Xoae_app app) { // NOLOCK.app_level + Xoae_wiki_mgr wiki_mgr = app.Wiki_mgr(); + int len = wiki_mgr.Count(); + for (int i = 0; i < len; ++i) { + Xowe_wiki wiki = (Xowe_wiki)wiki_mgr.Get_at(i); + wiki.Parser_mgr().Scrib().Core_term(); } } } 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 06f414120..bf65863d2 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 @@ -41,7 +41,7 @@ public class Scrib_invoke_func extends Pf_func_base { Scrib_core core = wiki.Parser_mgr().Scrib().Core(); if (core == null) { synchronized (this) { - core = wiki.Parser_mgr().Scrib().Core_make(ctx); + core = wiki.Parser_mgr().Scrib().Core_init(ctx); core.Init(); core.When_page_changed(ctx.Page()); } @@ -71,7 +71,7 @@ public class Scrib_invoke_func extends Pf_func_base { || err_filter_mgr.Count_eq_0( ) // err_filter_mgr exists, but no definitions || !err_filter_mgr.Match(String_.new_u8(mod_name), String_.new_u8(fnc_name), err.To_str__msg_only())) // NOTE: must be To_str__msg_only; err_filter_mgr has defintion and it doesn't match current; print warn; DATE:2015-07-24 ctx.App().Usr_dlg().Warn_many("", "", "invoke failed: ~{0} ~{1} ~{2}", ctx.Page().Ttl().Raw(), String_.new_u8(src, self.Src_bgn(), self.Src_end()), err.To_str__log()); - wiki.Parser_mgr().Scrib().Core_invalidate_when_page_changes(); // NOTE: invalidate core when page changes, not for rest of page, else page with many errors will be very slow due to multiple invalidations; PAGE:th.d:all; DATE:2014-10-03 + wiki.Parser_mgr().Scrib().Terminate_when_page_changes_y_(); // NOTE: terminate core when page changes; not terminating now, else page with many errors will be very slow due to multiple remakes of core; PAGE:th.d:all; DATE:2014-10-03 } } public static void Error(Bry_bfr bfr, Xow_msg_mgr msg_mgr, Err err) {Error(bfr, msg_mgr, Err_.cast_or_make(err).To_str__top_wo_args());}// NOTE: must use "short" error message to show in wikitext; DATE:2015-07-27 diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_lib.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_lib.java index 28f36e196..14caa8f00 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_lib.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_lib.java @@ -21,4 +21,5 @@ public interface Scrib_lib { Scrib_lib Init(); Scrib_lua_mod Register(Scrib_core core, Io_url script_dir); boolean Procs_exec(int key, Scrib_proc_args args, Scrib_proc_rslt rslt); + Scrib_lib Clone_lib(Scrib_core core); } diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_lib_mgr.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_lib_mgr.java index cb9d88944..609222836 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_lib_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_lib_mgr.java @@ -24,7 +24,7 @@ public class Scrib_lib_mgr { public void Init_for_core(Scrib_core core, Io_url script_dir) { int len = list.Count(); for (int i = 0; i < len; i++) { - Scrib_lib lib = Get_at(i); + Scrib_lib lib = Get_at(i).Clone_lib(core); lib.Register(core, script_dir); } } diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_proc_mgr.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_proc_mgr.java index e3df84380..4d8cc8532 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_proc_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_proc_mgr.java @@ -22,9 +22,7 @@ public class Scrib_proc_mgr { public Scrib_proc Get_by_key(String key) {synchronized (hash) {return (Scrib_proc)hash.Get_by(key);}} public Scrib_proc Get_at(int i) {synchronized (hash) {return (Scrib_proc)hash.Get_at(i);}} public void Set(String key, Scrib_proc proc) { -// synchronized (hash) { // LOCK:DELETE; DATE:2016-07-06 - hash.Add_if_dupe_use_nth(key, proc); // WORKAROUND: Add_if_dupe_use_nth b/c some libraries reuse proc name; EX: getGlobalSiteId is used by mw.wikibase.lua and mw.wikibase.entity.lua -// } + hash.Add_if_dupe_use_nth(key, proc); // WORKAROUND: Add_if_dupe_use_nth b/c some libraries reuse proc name; EX: getGlobalSiteId is used by mw.wikibase.lua and mw.wikibase.entity.lua } public Scrib_proc Set(Scrib_lib lib, String proc_name, int proc_id) { Scrib_proc proc = new Scrib_proc(lib, proc_name, proc_id); diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_xtn_mgr.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_xtn_mgr.java index d2e199008..428a2e7cb 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_xtn_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_xtn_mgr.java @@ -23,10 +23,14 @@ public class Scrib_xtn_mgr extends Xox_mgr_base { @Override public void Xtn_ctor_by_app(Xoae_app app) {this.app = app;} private Xoae_app app; @Override public Xox_mgr Xtn_clone_new() {return new Scrib_xtn_mgr();} public Scrib_lib_mgr Lib_mgr() {return lib_mgr;} private Scrib_lib_mgr lib_mgr = new Scrib_lib_mgr(); + @Override public void Enabled_(boolean v) { + Scrib_core_mgr.Term_all(app); + super.Enabled_(v); + } public byte Engine_type() {return engine_type;} private byte engine_type = Scrib_engine_type.Type_luaj; public void Engine_type_(byte cmd) { engine_type = cmd; - gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(); + gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(app); } public int Lua_timeout() {return lua_timeout;} private int lua_timeout = 4000; public int Lua_timeout_polling() {return lua_timeout_polling;} private int lua_timeout_polling = 1; @@ -36,7 +40,7 @@ public class Scrib_xtn_mgr extends Xox_mgr_base { public boolean Luaj_debug_enabled() {return luaj_debug_enabled;} private boolean luaj_debug_enabled; public void Luaj_debug_enabled_(boolean v) { this.luaj_debug_enabled = v; - gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all();// restart server in case luaj caches any debug data + gplx.xowa.xtns.scribunto.Scrib_core_mgr.Term_all(app);// restart server in case luaj caches any debug data } public Xop_log_invoke_wkr Invoke_wkr() {return invoke_wkr;} private Xop_log_invoke_wkr invoke_wkr; @Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/engines/mocks/Mock_scrib_fxt.java b/400_xowa/src/gplx/xowa/xtns/scribunto/engines/mocks/Mock_scrib_fxt.java index ba9cdda0b..a154d19e9 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/engines/mocks/Mock_scrib_fxt.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/engines/mocks/Mock_scrib_fxt.java @@ -27,7 +27,7 @@ public class Mock_scrib_fxt { Xoae_app app = Xoa_app_fxt.Make__app__edit(); Xowe_wiki wiki = Xoa_app_fxt.Make__wiki__edit(app, domain, app.Lang_mgr().Get_by_or_new(Bry_.new_u8(lang))); parser_fxt = new Xop_fxt(app, wiki); // NOTE: always new(); don't try to cache; causes errors in Language_lib - core = wiki.Parser_mgr().Scrib().Core_make(wiki.Parser_mgr().Ctx()); + core = wiki.Parser_mgr().Scrib().Core_init(wiki.Parser_mgr().Ctx()); core.Engine_(engine); engine.Clear(); core.Interpreter().Server_(server); Xot_invk parent_frame = new Xot_invk_temp(true); parent_frame.Frame_tid_(Scrib_frame_.Tid_null); diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_html.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_html.java index 965bca75d..2e0091786 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_html.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_html.java @@ -20,6 +20,7 @@ public class Scrib_lib_html implements Scrib_lib { public Scrib_lib_html(Scrib_core core) {} public Scrib_lua_mod Mod() {return mod;} private Scrib_lua_mod mod; public Scrib_lib Init() {procs.Init_by_lib(this, String_.Ary_empty); return this;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_html(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.html.lua")); diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_language.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_language.java index 97955abd8..65cfb4cad 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_language.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_language.java @@ -22,6 +22,7 @@ public class Scrib_lib_language implements Scrib_lib { public Scrib_lib_language(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;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_language(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.language.lua")); @@ -150,7 +151,7 @@ public class Scrib_lib_language implements Scrib_lib { private boolean Case_1st(Scrib_proc_args args, Scrib_proc_rslt rslt, boolean upper) { Xol_lang_itm lang = lang_(args); byte[] word = args.Pull_bry(1); - Bry_bfr bfr = core.Wiki().Appe().Utl__bfr_mkr().Get_b128().Mkr_rls(); + Bry_bfr bfr = core.Wiki().Utl__bfr_mkr().Get_b128().Mkr_rls(); return rslt.Init_obj(lang.Case_mgr().Case_build_1st(bfr, upper, word, 0, word.length)); } public boolean Lc(Scrib_proc_args args, Scrib_proc_rslt rslt) {return Case_all(args, rslt, Bool_.N);} @@ -181,7 +182,8 @@ public class Scrib_lib_language implements Scrib_lib { byte[] fmt_bry = args.Pull_bry(1); byte[] date_bry = args.Cast_bry_or_empty(2); // NOTE: optional empty is required b/c date is sometimes null; use Bry_.Empty b/c this is what Pft_func_time.ParseDate takes; DATE:2013-04-05 boolean utc = args.Cast_bool_or_n(3); - Bry_bfr tmp_bfr = core.App().Utl__bfr_mkr().Get_b512(); + Xowe_wiki wiki = core.Wiki(); + Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512(); Pft_fmt_itm[] fmt_ary = Pft_fmt_itm_.Parse(core.Ctx(), fmt_bry); DateAdp date = null; if (Bry_.Len_eq_0(date_bry)) @@ -198,7 +200,8 @@ public class Scrib_lib_language implements Scrib_lib { date = Pft_func_time.ParseDate(date_bry, utc, tmp_bfr); // NOTE: not using java's datetime parse b/c it is more strict; not reconstructing PHP's datetime parse b/c it is very complicated (state machine); re-using MW's parser b/c it is inbetween; DATE:2015-07-29 } if (date == null || tmp_bfr.Len() > 0) {tmp_bfr.Mkr_rls(); return rslt.Init_fail("bad argument #2 to 'formatDate' (not a valid timestamp)");} - Pft_func_formatdate.Date_bldr().Format(tmp_bfr, core.Wiki(), lang, date, fmt_ary); + + wiki.Parser_mgr().Date_fmt_bldr().Format(tmp_bfr, wiki, lang, date, fmt_ary); byte[] rv = tmp_bfr.To_bry_and_rls(); return rslt.Init_obj(rv); } diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_message.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_message.java index 30e2c192b..89dc601fd 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_message.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_message.java @@ -24,6 +24,7 @@ public class Scrib_lib_message implements Scrib_lib { public Scrib_lib_message(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;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_message(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.message.lua"));// NOTE: "lang" not passed in diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw.java index 60a608ce4..a32d41fc6 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw.java @@ -25,6 +25,7 @@ public class Scrib_lib_mw implements Scrib_lib { public Scrib_lua_mod Mod() {return mod;} public void Mod_(Scrib_lua_mod v) {this.mod = v;} private Scrib_lua_mod mod; public boolean Allow_env_funcs() {return allow_env_funcs;} private boolean allow_env_funcs = true; public Scrib_lib Init() {procs.Init_by_lib(this, Proc_names); return this;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_mw(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); core.RegisterInterface(this, script_dir.GenSubFil("mwInit.lua")); // DATE:2014-07-12 diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_site.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_site.java index fc8816880..8d0900b81 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_site.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_site.java @@ -23,6 +23,7 @@ public class Scrib_lib_site implements Scrib_lib { public Scrib_lib_site(Scrib_core core) {this.core = core;} private final 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 Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_site(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.site.lua"));// NOTE: info not passed by default; rely on Init_for_wiki 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 fed6c7832..881a8404a 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,18 +19,19 @@ package gplx.xowa.xtns.scribunto.libs; import gplx.*; import gplx.xowa.*; import import gplx.core.bits.*; import gplx.xowa.langs.msgs.*; 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(); + 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;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_text(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.text.lua")); notify_wiki_changed_fnc = mod.Fncs_get_by_key("notify_wiki_changed"); return mod; } private Scrib_lua_proc notify_wiki_changed_fnc; - public Scrib_proc_mgr Procs() {return procs;} private final Scrib_proc_mgr procs = new Scrib_proc_mgr(); + public Scrib_proc_mgr Procs() {return procs;} private final 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_unstrip: return Unstrip(args, rslt); @@ -46,7 +47,7 @@ public class Scrib_lib_text implements Scrib_lib { private static final int Proc_unstrip = 0, Proc_unstripNoWiki = 1, Proc_killMarkers = 2, Proc_getEntityTable = 3, Proc_init_text_for_wiki = 4, Proc_jsonEncode = 5, Proc_jsonDecode = 6; public static final String Invk_unstrip = "unstrip", Invk_unstripNoWiki = "unstripNoWiki", Invk_killMarkers = "killMarkers", Invk_getEntityTable = "getEntityTable" , Invk_init_text_for_wiki = "init_text_for_wiki", Invk_jsonEncode = "jsonEncode", Invk_jsonDecode = "jsonDecode"; - private static final String[] Proc_names = String_.Ary(Invk_unstrip, Invk_unstripNoWiki, Invk_killMarkers, Invk_getEntityTable, Invk_init_text_for_wiki, Invk_jsonEncode, Invk_jsonDecode); + private static final String[] Proc_names = String_.Ary(Invk_unstrip, Invk_unstripNoWiki, Invk_killMarkers, Invk_getEntityTable, Invk_init_text_for_wiki, Invk_jsonEncode, Invk_jsonDecode); public boolean Unstrip(Scrib_proc_args args, Scrib_proc_rslt rslt) {return rslt.Init_obj(args.Pull_str(0));} // NOTE: XOWA does not use MediaWiki strip markers; just return original; DATE:2015-01-20 public boolean UnstripNoWiki(Scrib_proc_args args, Scrib_proc_rslt rslt) {return rslt.Init_obj(args.Pull_str(0));} // NOTE: XOWA does not use MediaWiki strip markers; just return original; DATE:2015-01-20 public boolean KillMarkers(Scrib_proc_args args, Scrib_proc_rslt rslt) {return rslt.Init_obj(args.Pull_str(0));} // NOTE: XOWA does not use MediaWiki strip markers; just return original; DATE:2015-01-20 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 5e87429cd..7ea10704d 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 @@ -25,6 +25,7 @@ public class Scrib_lib_title implements Scrib_lib { public Scrib_lib_title(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;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_title(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.title.lua") @@ -84,7 +85,7 @@ public class Scrib_lib_title implements Scrib_lib { byte[] qry_bry = args.Extract_qry_args(wiki, 2); // byte[] proto = Scrib_kv_utl_.Val_to_bry_or(values, 3, null); // NOTE: Scribunto has more conditional logic around argument 2 and setting protocols; DATE:2014-07-07 Xoa_ttl ttl = Xoa_ttl.Parse(wiki, ttl_bry); if (ttl == null) return rslt.Init_obj(null); - Bry_bfr bfr = wiki.Appe().Utl__bfr_mkr().Get_b512(); + Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512(); //if (url_func_tid == Pfunc_urlfunc.Tid_full) { // if (proto == null) proto = Proto_relative; // Object proto_obj = proto_hash.Get_by(proto); if (proto_obj == null) throw Err_.new_fmt_("protocol is not valid: {0}", proto); @@ -134,12 +135,11 @@ public class Scrib_lib_title implements Scrib_lib { if (ttl == Xoa_ttl.Null) return rslt.Init_null(); // TODO_OLD: MW does extra logic here to cache ttl in ttl cache to avoid extra title lookups boolean ttl_exists = false, ttl_redirect = false; int ttl_id = 0; - synchronized (tmp_db_page) { - ttl_exists = core.Wiki().Db_mgr().Load_mgr().Load_by_ttl(tmp_db_page, ttl.Ns(), ttl.Page_db()); - } + Xowd_page_itm db_page = Xowd_page_itm.new_tmp(); + ttl_exists = core.Wiki().Db_mgr().Load_mgr().Load_by_ttl(db_page, ttl.Ns(), ttl.Page_db()); if (ttl_exists) { - ttl_redirect = tmp_db_page.Redirected(); - ttl_id = tmp_db_page.Id(); + ttl_redirect = db_page.Redirected(); + ttl_id = db_page.Id(); } Keyval[] rv = new Keyval[4]; rv[ 0] = Keyval_.new_("isRedirect" , ttl_redirect); // title.isRedirect @@ -226,6 +226,6 @@ public class Scrib_lib_title implements Scrib_lib { if (!ns_file_or_media) rv[rv_idx++] = Keyval_.new_("file" , false); // REF.MW: if ( $ns !== NS_FILE && $ns !== NS_MEDIA ) $ret['file'] = false; return rv; - } private static final Xowd_page_itm tmp_db_page = Xowd_page_itm.new_tmp(); + } public static final String Key_wikitext = "wikitext"; } diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_uri.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_uri.java index c26dfad14..e53790c5b 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_uri.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_uri.java @@ -23,6 +23,7 @@ public class Scrib_lib_uri implements Scrib_lib { public Scrib_lib_uri(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;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_uri(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.uri.lua")); // NOTE: defaultUrl handled by Init_lib_url @@ -46,8 +47,8 @@ public class Scrib_lib_uri implements Scrib_lib { private static final String[] Proc_names = String_.Ary(Invk_anchorEncode, Invk_localUrl, Invk_fullUrl, Invk_canonicalUrl, Invk_init_uri_for_page); public boolean AnchorEncode(Scrib_proc_args args, Scrib_proc_rslt rslt) { byte[] raw_bry = args.Pull_bry(0); - Bry_bfr bfr = core.App().Utl__bfr_mkr().Get_b512(); - Bry_bfr tmp_bfr = core.App().Utl__bfr_mkr().Get_b512(); + Bry_bfr bfr = core.Wiki().Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = core.Wiki().Utl__bfr_mkr().Get_b512(); Pfunc_anchorencode.Func_init(core.Ctx()); Pfunc_anchorencode.Anchor_encode(raw_bry, bfr, tmp_bfr); tmp_bfr.Clear_and_rls(); @@ -59,7 +60,7 @@ public class Scrib_lib_uri implements Scrib_lib { byte[] qry_bry = args.Extract_qry_args(wiki, 1); Xoa_ttl ttl = Xoa_ttl.Parse(wiki, ttl_bry); if (ttl == null) return rslt.Init_null(); - Bry_bfr bfr = core.App().Utl__bfr_mkr().Get_b512(); + Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512(); if (ttl.Ns().Id() == Xow_ns_.Tid__media) { // change "Media:" -> "File:" bfr.Add(wiki.Ns_mgr().Ns_file().Name_db_w_colon()); bfr.Add(ttl.Page_db()); diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring.java index 16ff934cf..2b994ec10 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring.java @@ -26,6 +26,7 @@ public class Scrib_lib_ustring implements Scrib_lib { public int Pattern_len_max() {return pattern_len_max;} public Scrib_lib_ustring Pattern_len_max_(int v) {pattern_len_max = v; return this;} private int pattern_len_max = 10000; private Scrib_regx_converter regx_converter = new Scrib_regx_converter(); public Scrib_lib Init() {procs.Init_by_lib(this, Proc_names); return this;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_ustring(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.ustring.lua") diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase.java index e0c9b4ea6..6680b64a4 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase.java @@ -22,6 +22,7 @@ public class Scrib_lib_wikibase implements Scrib_lib { public Scrib_lib_wikibase(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;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_wikibase(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.wikibase.lua")); @@ -93,7 +94,8 @@ public class Scrib_lib_wikibase implements Scrib_lib { return rslt.Init_obj(core.Wiki().Domain_abrv()); // ;siteGlobalID: This site's global ID (e.g. 'itwiki'), as used in the sites table. Default: $wgDBname.; REF:/xtns/Wikibase/docs/options.wiki } private Wdata_doc Get_wdoc(byte[] xid_bry) { - Wdata_doc wdoc = core.Wiki().Appe().Wiki_mgr().Wdata_mgr().Doc_mgr.Get_by_xid_or_null(xid_bry); // NOTE: by_xid b/c Module passes just "p1" not "Property:P1" + Xowe_wiki wiki = core.Wiki(); + Wdata_doc wdoc = wiki.Appe().Wiki_mgr().Wdata_mgr().Doc_mgr.Get_by_xid_or_null(xid_bry); // NOTE: by_xid b/c Module passes just "p1" not "Property:P1" if (wdoc == null) Wdata_wiki_mgr.Log_missing_qid(core.Ctx(), xid_bry); return wdoc; } diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_entity.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_entity.java index 38727730b..57d7ad57b 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_entity.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_entity.java @@ -22,6 +22,7 @@ public class Scrib_lib_wikibase_entity implements Scrib_lib { public Scrib_lib_wikibase_entity(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;} + public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_wikibase_entity(core);} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.wikibase.entity.lua")); @@ -52,7 +53,7 @@ public class Scrib_lib_wikibase_entity implements Scrib_lib { if (pid_int == Wdata_wiki_mgr.Pid_null) pid_int = wdata_mgr.Pid_mgr.Get_or_null(lang, pid); // parse as name; EX: name > 123 if (pid_int == Wdata_wiki_mgr.Pid_null) return rslt.Init_str_empty(); Wdata_claim_grp prop_grp = wdoc.Claim_list_get(pid_int); if (prop_grp == null) return rslt.Init_str_empty(); - Bry_bfr bfr = app.Utl__bfr_mkr().Get_b512(); + Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512(); wdata_mgr.Resolve_to_bfr(bfr, prop_grp, lang); return rslt.Init_obj(bfr.To_bry_and_rls()); } diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl.java index 79b416afe..308717168 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_wikibase_srl.java @@ -90,37 +90,38 @@ class Scrib_lib_wikibase_srl { } private static Keyval[] Srl_claims(int base_adj, boolean legacy_style, Ordered_hash claim_grps) { int len = claim_grps.Count(); if (len == 0) return null; + Scrib_lib_wikibase_srl_visitor visitor = new Scrib_lib_wikibase_srl_visitor(); int rv_len = legacy_style ? len * 2 : len; // NOTE: legacyStyle returns 2 sets of properties: official "P" and legacy "p"; DATE:2014-05-11 Keyval[] rv = new Keyval[rv_len]; for (int i = 0; i < len; i++) { Wdata_claim_grp grp = (Wdata_claim_grp)claim_grps.Get_at(i); String pid_str = Int_.To_str(grp.Id()); - Keyval[] grp_val = Srl_claims_prop_grp("P" + pid_str, grp, base_adj); + Keyval[] grp_val = Srl_claims_prop_grp(visitor, "P" + pid_str, grp, base_adj); rv[i] = Keyval_.new_("P" + pid_str, grp_val); if (legacy_style) rv[i + len] = Keyval_.new_("p" + pid_str, grp_val); // SEE:WikibaseLuaBindings.php; This is a B/C hack to allow existing lua code to use hardcoded IDs in both lower (legacy) and upper case.; DATE:2014-05-11 } return rv; } - private static Keyval[] Srl_claims_prop_grp(String pid, Wdata_claim_grp grp, int base_adj) { + private static Keyval[] Srl_claims_prop_grp(Scrib_lib_wikibase_srl_visitor visitor, String pid, Wdata_claim_grp grp, int base_adj) { int len = grp.Len(); Keyval[] rv = new Keyval[len]; for (int i = 0; i < len; i++) { Wdata_claim_itm_core itm = grp.Get_at(i); - rv[i] = Keyval_.int_(i + base_adj, Srl_claims_prop_itm(pid, itm, base_adj)); // NOTE: must be super 0 or super 1; DATE:2014-05-09 + rv[i] = Keyval_.int_(i + base_adj, Srl_claims_prop_itm(visitor, pid, itm, base_adj)); // NOTE: must be super 0 or super 1; DATE:2014-05-09 } return rv; } - private static Keyval[] Srl_claims_prop_itm(String pid, Wdata_claim_itm_core itm, int base_adj) { + private static Keyval[] Srl_claims_prop_itm(Scrib_lib_wikibase_srl_visitor visitor, String pid, Wdata_claim_itm_core itm, int base_adj) { List_adp list = List_adp_.New(); list.Add(Keyval_.new_("id", pid)); - list.Add(Keyval_.new_("mainsnak", Srl_claims_prop_itm_core(pid, itm))); + list.Add(Keyval_.new_("mainsnak", Srl_claims_prop_itm_core(visitor, pid, itm))); list.Add(Keyval_.new_(Wdata_dict_claim_v1.Str_rank, Wdata_dict_rank.Xto_str(itm.Rank_tid()))); list.Add(Keyval_.new_("type", itm.Prop_type())); - Srl_root(list, Wdata_dict_claim.Str_qualifiers, Srl_qualifiers(itm.Qualifiers(), base_adj)); + Srl_root(list, Wdata_dict_claim.Str_qualifiers, Srl_qualifiers(visitor, itm.Qualifiers(), base_adj)); return (Keyval[])list.To_ary_and_clear(Keyval.class); } - private static Keyval[] Srl_qualifiers(Wdata_claim_grp_list list, int base_adj) { + private static Keyval[] Srl_qualifiers(Scrib_lib_wikibase_srl_visitor visitor, Wdata_claim_grp_list list, int base_adj) { if (list == null) return null; int list_len = list.Len(); if (list_len == 0) return Keyval_.Ary_empty; List_adp rv = List_adp_.New(); @@ -132,25 +133,24 @@ class Scrib_lib_wikibase_srl { String itm_pid = grp.Id_str(); for (int j = 0; j < grp_len; ++j) { Wdata_claim_itm_core itm = grp.Get_at(j); - pid_list.Add(Keyval_.int_(j + base_adj, Srl_claims_prop_itm_core(itm_pid, itm))); // NOTE: was originally "+ 1"; changed to base_adj; PAGE:ru.w:Tor ru.w:Кактусовые DATE:2014-10-25 + pid_list.Add(Keyval_.int_(j + base_adj, Srl_claims_prop_itm_core(visitor, itm_pid, itm))); // NOTE: was originally "+ 1"; changed to base_adj; PAGE:ru.w:Tor ru.w:Кактусовые DATE:2014-10-25 } rv.Add(Keyval_.new_(itm_pid, (Keyval[])pid_list.To_ary_and_clear(Keyval.class))); } return (Keyval[])rv.To_ary_and_clear(Keyval.class); } - private static Keyval[] Srl_claims_prop_itm_core(String pid, Wdata_claim_itm_core itm) { + private static Keyval[] Srl_claims_prop_itm_core(Scrib_lib_wikibase_srl_visitor visitor, String pid, Wdata_claim_itm_core itm) { boolean snak_is_valued = itm.Snak_tid() == Wdata_dict_snak_tid.Tid_value; // PURPOSE: was != Wdata_dict_snak_tid.Tid_novalue; PAGE:it.s:Autore:Anonimo DATE:2015-12-06 int snak_is_valued_adj = snak_is_valued ? 1 : 0; Keyval[] rv = new Keyval[3 + snak_is_valued_adj]; if (snak_is_valued) // NOTE: novalue must not return slot (no datavalue node in json); PAGE:ru.w:Лимонов,_Эдуард_Вениаминович; DATE:2015-02-16; ALSO: sv.w:Joseph_Jaquet; DATE:2015-07-31 - rv[0] = Keyval_.new_("datavalue", Srl_claims_prop_itm_core_val(itm)); + rv[0] = Keyval_.new_("datavalue", Srl_claims_prop_itm_core_val(visitor, itm)); rv[0 + snak_is_valued_adj] = Keyval_.new_("property", pid); rv[1 + snak_is_valued_adj] = Keyval_.new_("snaktype", Wdata_dict_snak_tid.Xto_str(itm.Snak_tid())); rv[2 + snak_is_valued_adj] = Keyval_.new_("datatype", Wdata_dict_val_tid.To_str__srl(itm.Val_tid())); // NOTE: datatype needed for Modules; PAGE:eo.w:WikidataKoord; DATE:2015-11-08 return rv; } - private static final Scrib_lib_wikibase_srl_visitor visitor = new Scrib_lib_wikibase_srl_visitor(); - private static Keyval[] Srl_claims_prop_itm_core_val(Wdata_claim_itm_core itm) { + private static Keyval[] Srl_claims_prop_itm_core_val(Scrib_lib_wikibase_srl_visitor visitor, Wdata_claim_itm_core itm) { switch (itm.Snak_tid()) { case Wdata_dict_snak_tid.Tid_somevalue: return Datavalue_somevalue; case Wdata_dict_snak_tid.Tid_novalue: return Datavalue_novalue; // TODO_OLD: throw exc diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Xow_wiki_tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Xow_wiki_tst.java index bde4a5019..24eb0ca61 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Xow_wiki_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Xow_wiki_tst.java @@ -20,7 +20,7 @@ import org.junit.*; public class Xow_wiki_tst { @Before public void init() {fxt.Clear();} private Xow_wiki_fxt fxt = new Xow_wiki_fxt(); @Test public void Load_page_and_parse() { // PURPOSE.fix: unknown page causes null reference error in scribunto; DATE:2013-08-27 - fxt.Fxt().Wiki().Parser_mgr().Scrib().Core_make(fxt.Fxt().Ctx()); + fxt.Fxt().Wiki().Parser_mgr().Scrib().Core_init(fxt.Fxt().Ctx()); fxt.Test_getPageByTtl("Does_not_exist", null); } } diff --git a/400_xowa/src/gplx/xowa/xtns/titleBlacklists/Blacklist_scrib_lib.java b/400_xowa/src/gplx/xowa/xtns/titleBlacklists/Blacklist_scrib_lib.java index de319e436..667cf142c 100644 --- a/400_xowa/src/gplx/xowa/xtns/titleBlacklists/Blacklist_scrib_lib.java +++ b/400_xowa/src/gplx/xowa/xtns/titleBlacklists/Blacklist_scrib_lib.java @@ -20,6 +20,7 @@ import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.scribunto.libs.*; public class Blacklist_scrib_lib implements Scrib_lib { 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 Scrib_lib Clone_lib(Scrib_core core) {return new Blacklist_scrib_lib();} public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) { Init(); mod = core.RegisterInterface(this, core.App().Fsys_mgr().Bin_xtns_dir().GenSubFil_nest("TitleBlacklist", "mw.ext.TitleBlacklist.lua")); @@ -34,7 +35,7 @@ public class Blacklist_scrib_lib implements Scrib_lib { } private static final int Proc_test = 0; public static final String Invk_test = "test"; - private static final String[] Proc_names = String_.Ary(Invk_test); + private static final String[] Proc_names = String_.Ary(Invk_test); public boolean Test(Scrib_proc_args args, Scrib_proc_rslt rslt) { return rslt.Init_null(); // assume all titles are blacklisted; note that this info is not available; } diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_doc_mgr.java b/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_doc_mgr.java index b1dcbe3eb..224a48b91 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_doc_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_doc_mgr.java @@ -26,18 +26,29 @@ public class Wbase_doc_mgr { this.hash = app.Cache_mgr().Doc_cache(); } public void Enabled_(boolean v) {this.enabled = v;} private boolean enabled; - public void Clear() {hash.Clear();} - public void Add(byte[] full_db, Wdata_doc page) {hash.Add(full_db, page);} // TEST: + public void Clear() { + synchronized (hash) { // LOCK:app-level + hash.Clear(); + } + } + public void Add(byte[] full_db, Wdata_doc page) { // TEST: + synchronized (hash) { // LOCK:app-level + if (hash.Get_or_null(full_db) == null) + hash.Add(full_db, page); + } + } public Wdata_doc Get_by_ttl_or_null(Xowe_wiki wiki, Xoa_ttl ttl) { byte[] qid_bry = qid_mgr.Get_or_null(wiki, ttl); // EX: "enwiki","Earth" -> "Q2" return qid_bry == null ? null : this.Get_by_bry_or_null(qid_bry); } public Wdata_doc Get_by_xid_or_null(byte[] xid) {return Get_by_bry_or_null(Prepend_property_if_needed(xid));}// scribunto passes either p1 or q1; convert p1 to "Property:P1" - public Wdata_doc Get_by_bry_or_null(byte[] full_db) { // must be format like "Q2" or "Property:P1" + public Wdata_doc Get_by_bry_or_null(byte[] full_db) { // must be correct format; EX:"Q2" or "Property:P1" Wdata_doc rv = hash.Get_or_null(full_db); if (rv == null) { byte[] page_src = Load_or_null(full_db); if (page_src == null) return null; // page not found - rv = new Wdata_doc(full_db, wbase_mgr, wbase_mgr.Jdoc_parser().Parse(page_src)); + synchronized (hash) { // LOCK:app-level; both hash and jdoc_parser + rv = new Wdata_doc(full_db, wbase_mgr, wbase_mgr.Jdoc_parser().Parse(page_src)); + } Add(full_db, rv); } return rv; @@ -46,7 +57,7 @@ public class Wbase_doc_mgr { if (!enabled) return null; Xoa_ttl page_ttl = Xoa_ttl.Parse(wbase_mgr.Wdata_wiki(), full_db); if (page_ttl == null) {app.Usr_dlg().Warn_many("", "", "invalid qid for ttl: qid=~{0}", full_db); return null;} Xoae_page page_itm = wbase_mgr.Wdata_wiki().Data_mgr().Load_page_by_ttl(page_ttl); - return page_itm.Db().Page().Exists_n() ? null : page_itm.Db().Text().Text_bry(); + return page_itm.Db().Page().Exists() ? page_itm.Db().Text().Text_bry() : null; } private static byte[] Prepend_property_if_needed(byte[] bry) { diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_pid_mgr.java b/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_pid_mgr.java index 61cf250a1..30564898c 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_pid_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_pid_mgr.java @@ -21,8 +21,17 @@ public class Wbase_pid_mgr { // EX: "en|road_map" -> 15 ("Property:P15") private final Hash_adp_bry hash = Hash_adp_bry.cs(); public Wbase_pid_mgr(Wdata_wiki_mgr wbase_mgr) {this.wbase_mgr = wbase_mgr;} public void Enabled_(boolean v) {this.enabled = v;} private boolean enabled; - public void Clear() {hash.Clear();} - public void Add(byte[] pid_key, int pid_id) {hash.Add_bry_int(pid_key, pid_id);} + public void Clear() { + synchronized (hash) { // LOCK:app-level + hash.Clear(); + } + } + public void Add(byte[] pid_key, int pid_id) { + synchronized (hash) { // LOCK:app-level + if (!hash.Has(pid_key)) + hash.Add_bry_int(pid_key, pid_id); + } + } public int Get_or_null(byte[] lang_key, byte[] pid_name) { if (!enabled) return Wdata_wiki_mgr.Pid_null; byte[] pid_key = Bry_.Add(lang_key, Byte_ascii.Pipe_bry, pid_name); // EX: "en|road_map" diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_qid_mgr.java b/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_qid_mgr.java index a8aec9dc0..aec0a7e17 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_qid_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/Wbase_qid_mgr.java @@ -20,16 +20,20 @@ import gplx.xowa.wikis.domains.*; public class Wbase_qid_mgr {// EX: "enwiki|0|Earth" -> "Q2" private final Wdata_wiki_mgr wbase_mgr; private final Hash_adp_bry hash = Hash_adp_bry.cs(); - private final gplx.core.primitives.Int_obj_ref tmp_wiki_tid = gplx.core.primitives.Int_obj_ref.New_zero(); + private final gplx.core.primitives.Int_obj_ref tmp_wiki_tid = gplx.core.primitives.Int_obj_ref.New_zero(); // NOTE: return value is not checked; only used for function signature public Wbase_qid_mgr(Wdata_wiki_mgr wbase_mgr) { this.wbase_mgr = wbase_mgr; } public void Enabled_(boolean v) {this.enabled = v;} private boolean enabled; - public void Clear() {hash.Clear();} + public void Clear() { + synchronized (hash) { // LOCK:app-level + hash.Clear(); + } + } public void Add(Bry_bfr bfr, byte[] lang_key, int wiki_tid, byte[] ns_num, byte[] ttl, byte[] qid) { // TEST: Xow_abrv_wm_.To_abrv(bfr, lang_key, tmp_wiki_tid.Val_(wiki_tid)); byte[] qids_key = bfr.Add_byte(Byte_ascii.Pipe).Add(ns_num).Add_byte(Byte_ascii.Pipe).Add(ttl).To_bry(); - hash.Add(qids_key, qid); + this.Add(qids_key, qid); } public byte[] Get_or_null(Xowe_wiki wiki, Xoa_ttl ttl) {return Get_or_null(wiki.Wdata_wiki_abrv(), ttl);} public byte[] Get_or_null(byte[] wiki_abrv, Xoa_ttl ttl) { @@ -40,8 +44,14 @@ public class Wbase_qid_mgr {// EX: "enwiki|0|Earth" -> "Q2" if (rv == null) { // not in cache; load from db rv = wbase_mgr.Wdata_wiki().Db_mgr().Load_mgr().Load_qid(wiki_abrv, ttl.Ns().Num_bry(), ttl.Page_db()); byte[] val_for_hash = rv == null ? Bry_.Empty : rv; // JAVA: hashtable does not accept null as value; use Bry_.Empty - hash.Add(key, val_for_hash); // NOTE: if not in db, will insert Bry_.Empty; DATE:2014-07-23 + this.Add(key, val_for_hash); // NOTE: if not in db, will insert Bry_.Empty; DATE:2014-07-23 } return Bry_.Len_eq_0(rv) ? null : rv; // JAVA: convert Bry_.Empty to null which is what callers expect } + private void Add(byte[] key, byte[] val) { + synchronized (hash) { // LOCK:app-level + if (!hash.Has(key)) + hash.Add(key, val); + } + } } diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_wiki_mgr.java b/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_wiki_mgr.java index a67c6678f..f7acafd42 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_wiki_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_wiki_mgr.java @@ -28,6 +28,7 @@ public class Wdata_wiki_mgr implements Gfo_evt_itm, Gfo_invk { private final Wdata_prop_val_visitor prop_val_visitor; private final Wdata_doc_parser wdoc_parser_v1 = new Wdata_doc_parser_v1(), wdoc_parser_v2 = new Wdata_doc_parser_v2(); private Wdata_hwtr_mgr hwtr_mgr; + private final Bry_bfr tmp_bfr = Bry_bfr_.New_w_size(32); public Wdata_wiki_mgr(Xoae_app app) { this.app = app; this.evt_mgr = new Gfo_evt_mgr(this); @@ -60,9 +61,11 @@ public class Wdata_wiki_mgr implements Gfo_evt_itm, Gfo_invk { } public Xop_log_property_wkr Property_wkr() {return property_wkr;} private Xop_log_property_wkr property_wkr; public void Clear() { - Qid_mgr.Clear(); - Pid_mgr.Clear(); - Doc_mgr.Clear(); + synchronized (wdoc_parser_v2) { // LOCK:app-level + Qid_mgr.Clear(); + Pid_mgr.Clear(); + Doc_mgr.Clear(); + } } public byte[] Get_claim_or(Xow_domain_itm domain, Xoa_ttl page_ttl, int pid, byte[] or) { byte[] qid = this.Qid_mgr.Get_or_null(domain.Abrv_wm(), page_ttl); if (qid == null) return or; @@ -74,7 +77,7 @@ public class Wdata_wiki_mgr implements Gfo_evt_itm, Gfo_invk { claim_itm.Welcome(prop_val_visitor); return tmp_bfr.To_bry_and_clear(); } - } private final Bry_bfr tmp_bfr = Bry_bfr_.New_w_size(32); + } public void Resolve_to_bfr(Bry_bfr bfr, Wdata_claim_grp prop_grp, byte[] lang_key) { synchronized (this) { // LOCK:must synchronized b/c prop_val_visitor has member bfr which can get overwritten; DATE:2016-07-06 Hwtr_mgr_assert(); @@ -121,13 +124,11 @@ public class Wdata_wiki_mgr implements Gfo_evt_itm, Gfo_invk { } private void Hwtr_msgs_make() { if (!app.Wiki_mgr().Wiki_regy().Has(Xow_domain_itm_.Bry__wikidata)) return; -// synchronized (this) { // LOCK:DELETE; DATE:2016-07-06 - Xol_lang_itm new_lang = app.Usere().Lang(); - Xowe_wiki cur_wiki = this.Wdata_wiki(); - cur_wiki.Xtn_mgr().Xtn_wikibase().Load_msgs(cur_wiki, new_lang); - Wdata_hwtr_msgs hwtr_msgs = Wdata_hwtr_msgs.new_(cur_wiki.Msg_mgr()); - hwtr_mgr.Init_by_lang(hwtr_msgs); -// } + Xol_lang_itm new_lang = app.Usere().Lang(); + Xowe_wiki cur_wiki = this.Wdata_wiki(); + cur_wiki.Xtn_mgr().Xtn_wikibase().Load_msgs(cur_wiki, new_lang); + Wdata_hwtr_msgs hwtr_msgs = Wdata_hwtr_msgs.new_(cur_wiki.Msg_mgr()); + hwtr_mgr.Init_by_lang(hwtr_msgs); } public static void Write_json_as_html(Json_parser jdoc_parser, Bry_bfr bfr, byte[] data_raw) { bfr.Add(Xoh_consts.Span_bgn_open).Add(Xoh_consts.Id_atr).Add(Html_json_id).Add(Xoh_consts.__end_quote); // diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_wiki_mgr_fxt.java b/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_wiki_mgr_fxt.java index a91fc0445..d605157a9 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_wiki_mgr_fxt.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_wiki_mgr_fxt.java @@ -80,7 +80,7 @@ public class Wdata_wiki_mgr_fxt { } } public void Init_qids_add(String lang_key, int wiki_tid, String ttl, String qid) { - Bry_bfr tmp_bfr = app.Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512(); wdata_mgr.Qid_mgr.Add(tmp_bfr, Bry_.new_a7(lang_key), wiki_tid, Bry_.new_a7("000"), Bry_.new_a7(ttl), Bry_.new_a7(qid)); tmp_bfr.Mkr_rls(); } @@ -145,7 +145,7 @@ public class Wdata_wiki_mgr_fxt { parser_fxt.Page_ttl_("Q1_en"); parser_fxt.Exec_parse_page_all_as_str(raw); - Bry_bfr tmp_bfr = wiki.Appe().Utl__bfr_mkr().Get_b512(); + Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512(); wdata_lang_wtr.Page_(page).Bfr_arg__add(tmp_bfr); Tfds.Eq_str_lines(expd, tmp_bfr.To_str_and_rls()); @@ -168,7 +168,7 @@ public class Wdata_wiki_mgr_fxt { public void Test_write_json_as_html(String raw_str, String expd) { byte[] raw_bry = Bry_.new_a7(raw_str); raw_bry = gplx.langs.jsons.Json_parser_tst.Replace_apos(raw_bry); - Bry_bfr bfr = app.Utl__bfr_mkr().Get_b512(); + Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512(); Wdata_wiki_mgr.Write_json_as_html(wdata_mgr.Jdoc_parser(), bfr, raw_bry); Tfds.Eq(expd, bfr.To_str_and_rls()); } diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_xwiki_link_wtr.java b/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_xwiki_link_wtr.java index 93bd606f6..1bba460ad 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_xwiki_link_wtr.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/Wdata_xwiki_link_wtr.java @@ -39,7 +39,7 @@ public class Wdata_xwiki_link_wtr implements gplx.core.brys.Bfr_arg { Wdata_doc doc = wdata_mgr.Doc_mgr.Get_by_ttl_or_null(wiki, ttl); if (doc == null) return Qid_null; // no links boolean external_links_mgr_enabled = external_links_mgr.Enabled(); Ordered_hash links = doc.Slink_list(); - Bry_bfr tmp_bfr = wiki.Appe().Utl__bfr_mkr().Get_k004(); + Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_k004(); int len = links.Count(); for (int i = 0; i < len; i++) { Wdata_sitelink_itm slink = (Wdata_sitelink_itm)links.Get_at(i); diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/imports/Xob_wdata_db_cmd.java b/400_xowa/src/gplx/xowa/xtns/wdatas/imports/Xob_wdata_db_cmd.java index 623ab6800..ed4f40e19 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/imports/Xob_wdata_db_cmd.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/imports/Xob_wdata_db_cmd.java @@ -406,7 +406,7 @@ class Wdata_qual_tbl extends Wdata_tbl_base { private static final String Fld_qual_id = "qual_id", Fld_page_id = "page_id", Fld_val_text = "val_text"; } class Xob_wdata_db_visitor implements Wdata_claim_visitor { - private final Wdata_wiki_mgr wdata_mgr; private byte[] lang_key; + private final Wdata_wiki_mgr wdata_mgr; private byte[] lang_key; public Xob_wdata_db_visitor(Wdata_wiki_mgr wdata_mgr) {this.wdata_mgr = wdata_mgr;} public void Init(byte[] lang_key) {this.lang_key = lang_key;} public byte[] Rv() {return rv;} private byte[] rv; diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/pfuncs/Wdata_external_lang_links_data.java b/400_xowa/src/gplx/xowa/xtns/wdatas/pfuncs/Wdata_external_lang_links_data.java index 4ba523f77..56ff173ea 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/pfuncs/Wdata_external_lang_links_data.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/pfuncs/Wdata_external_lang_links_data.java @@ -41,7 +41,7 @@ public class Wdata_external_lang_links_data { if (Bry_.Eq(argx, Key_sort)) {sort = true; return;} // {{noexternallanglinks:*}}; assume it cannot be combined with other langs_hash: EX: {{noexternallanglinks:*|en|fr}} int args_len = self.Args_len(); Langs_add(argx); - Bry_bfr tmp_bfr = ctx.App().Utl__bfr_mkr().Get_b128(); + Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b128(); for (int i = 0; i < args_len; i++) { Arg_nde_tkn nde = self.Args_get_by_idx(i); nde.Val_tkn().Tmpl_evaluate(ctx, src, caller, tmp_bfr); // NOTE: changed from self to caller; DATE:2016-03-16 diff --git a/400_xowa/src/gplx/xowa/xtns/wdatas/specials/Wdata_itemByTitle_page.java b/400_xowa/src/gplx/xowa/xtns/wdatas/specials/Wdata_itemByTitle_page.java index 67f3b6b9b..90d1fed16 100644 --- a/400_xowa/src/gplx/xowa/xtns/wdatas/specials/Wdata_itemByTitle_page.java +++ b/400_xowa/src/gplx/xowa/xtns/wdatas/specials/Wdata_itemByTitle_page.java @@ -58,10 +58,10 @@ public class Wdata_itemByTitle_page implements Xow_special_page { } private static boolean Navigate(Gfo_usr_dlg usr_dlg, Xoae_app app, Wdata_wiki_mgr wdata_mgr, Xoae_page page, byte[] site_bry, byte[] page_bry) { page_bry = gplx.langs.htmls.encoders.Gfo_url_encoder_.Http_url.Decode(page_bry); // NOTE: space is converted to + on postback to url; decode - byte[] wiki_domain = Xow_abrv_wm_.Parse_to_domain_bry(site_bry); if (wiki_domain == null) {usr_dlg.Warn_many("", "", "site_bry parse failed; site_bry:~{0}", String_.new_u8(site_bry)); return false;} - Xowe_wiki wiki = app.Wiki_mgr().Get_by_or_make(wiki_domain); if (wiki == null) {usr_dlg.Warn_many("", "", "wiki_domain does not exist; wiki_domain:~{0}", String_.new_u8(wiki_domain)); return false;} - Xoa_ttl wdata_ttl = Xoa_ttl.Parse(wiki, page_bry); if (wdata_ttl == null) {usr_dlg.Warn_many("", "", "ttl is invalid; ttl:~{0}", String_.new_u8(page_bry)); return false;} - Wdata_doc doc = wdata_mgr.Doc_mgr.Get_by_ttl_or_null(wiki, wdata_ttl); if (doc == null) {usr_dlg.Warn_many("", "", "ttl cannot be found in wikidata; ttl:~{0}", String_.new_u8(wdata_ttl.Raw())); return false;} + byte[] wiki_domain = Xow_abrv_wm_.Parse_to_domain_bry(site_bry); if (wiki_domain == null) {usr_dlg.Warn_many("", "", "site_bry parse failed; site_bry:~{0}", String_.new_u8(site_bry)); return false;} + Xowe_wiki wiki = app.Wiki_mgr().Get_by_or_make(wiki_domain); if (wiki == null) {usr_dlg.Warn_many("", "", "wiki_domain does not exist; wiki_domain:~{0}", String_.new_u8(wiki_domain)); return false;} + Xoa_ttl wdata_ttl = Xoa_ttl.Parse(wiki, page_bry); if (wdata_ttl == null) {usr_dlg.Warn_many("", "", "ttl is invalid; ttl:~{0}", String_.new_u8(page_bry)); return false;} + Wdata_doc doc = wdata_mgr.Doc_mgr.Get_by_ttl_or_null(wiki, wdata_ttl); if (doc == null) {usr_dlg.Warn_many("", "", "ttl cannot be found in wikidata; ttl:~{0}", String_.new_u8(wdata_ttl.Raw())); return false;} byte[] qid_bry = doc.Qid(); wdata_mgr.Wdata_wiki().Data_mgr().Redirect(page, qid_bry); if (page.Db().Page().Exists_n()) {usr_dlg.Warn_many("", "", "qid cannot be found in wikidata; qid:~{0}", String_.new_u8(qid_bry)); return false;} return true;