1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

Dev: Add synchronized block when loading lang [#330]

This commit is contained in:
gnosygnu
2019-02-10 08:33:58 -05:00
parent 571f0a2388
commit e80dfc6adc
23 changed files with 94 additions and 86 deletions

View File

@@ -33,21 +33,29 @@ public class Xoa_lang_mgr implements Gfo_invk {
public int Len() {return hash.Count();}
public void Add(Xol_lang_itm itm) {hash.Add(itm.Key_bry(), itm);}
public Io_url Root_dir() {return root_dir;} private final Io_url root_dir;
public Xol_lang_itm Get_at(int i) {return (Xol_lang_itm)hash.Get_at(i);}
public Xol_lang_itm Get_by(byte[] key) {return (Xol_lang_itm)hash.Get_by(key);}
public Xol_lang_itm Get_by_or_load(byte[] key) {return Get_by_or_new(key).Init_by_load_assert();}
public Xol_lang_itm Get_by_or_en(byte[] key) { // called by Xowv_wiki for its .Lang()
Xol_lang_itm rv = Get_by(key);
return rv == null ? lang_en : rv;
public Xol_lang_itm Get_by_or_null(byte[] key) {return (Xol_lang_itm)hash.Get_by(key);} // check if exists
public Xol_lang_itm Get_by_or_load(byte[] key) { // main call
Xol_lang_itm rv = Get_by_or_null(key);
if (rv == null) {
rv = Xol_lang_itm.New(this, key);
rv.Init_by_load();
this.Add(rv);
}
return rv;
}
public Xol_lang_itm Get_by_or_new(byte[] key) {
Xol_lang_itm rv = Get_by(key);
public Xol_lang_itm Get_by_or_new(byte[] key) { // largely deprecated; should only be used for builders
Xol_lang_itm rv = Get_by_or_null(key);
if (rv == null) {
rv = Xol_lang_itm.New(this, key);
this.Add(rv);
}
return rv;
}
public Xol_lang_itm Get_at(int i) {return (Xol_lang_itm)hash.Get_at(i);} // called by Xol_mw_lang_parser
public Xol_lang_itm Get_by_or_en(byte[] key) { // called by Xowv_wiki to set .Lang() for DRD
Xol_lang_itm rv = Get_by_or_null(key);
return rv == null ? lang_en : rv;
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_get)) return Get_by_or_new(m.ReadBry("key"));
else if (ctx.Match(k, Invk_mediawiki_converter)) return mw_converter;

View File

@@ -21,6 +21,7 @@ import gplx.xowa.apps.gfs.*; import gplx.xowa.apps.fsys.*; import gplx.core.intl
import gplx.xowa.guis.langs.*;
public class Xol_lang_itm implements Gfo_invk {
private boolean loaded = false;
private final Object thread_lock = new Object();
public Xol_lang_itm(Xoa_lang_mgr lang_mgr, byte[] key_bry) {
this.lang_mgr = lang_mgr; this.key_bry = key_bry; this.key_str = String_.new_u8(key_bry);
Xol_lang_stub lang_itm = Xol_lang_stub_.Get_by_key_or_null(key_bry); if (lang_itm == null) throw Err_.new_wo_type("unknown lang_key", "key", String_.new_u8(key_bry));
@@ -32,7 +33,6 @@ public class Xol_lang_itm implements Gfo_invk {
this.specials_mgr = new Xol_specials_mgr(this);
this.case_mgr = Env_.Mode_testing() ? Xol_case_mgr_.A7() : Xol_case_mgr_.U8(); // NOTE: if test load ascii b/c utf8 is large; NOTE: placed here b/c tests do not call load; DATE:2014-07-04
this.num_mgr = Xol_num_mgr_.new_by_lang_id(lang_id);
this.lnki_trail_mgr = new Xol_lnki_trail_mgr(this);
this.vnt_mgr = new Xol_vnt_mgr(this);
this.grammar = Xol_grammar_.new_by_lang_id(lang_id);
this.gender = Xol_gender_.new_by_lang_id(lang_id);
@@ -78,7 +78,7 @@ public class Xol_lang_itm implements Gfo_invk {
public Xol_gender Gender() {return gender;} private final Xol_gender gender;
public Xol_plural Plural() {return plural;} private final Xol_plural plural;
public Xol_duration_mgr Duration_mgr() {return duration_mgr;} private final Xol_duration_mgr duration_mgr;
public Xol_lnki_trail_mgr Lnki_trail_mgr() {return lnki_trail_mgr;} private final Xol_lnki_trail_mgr lnki_trail_mgr;
public Xol_lnki_trail_mgr Lnki_trail_mgr() {return lnki_trail_mgr;} private final Xol_lnki_trail_mgr lnki_trail_mgr = new Xol_lnki_trail_mgr();
public Xop_lnki_arg_parser Lnki_arg_parser() {return lnki_arg_parser;} private Xop_lnki_arg_parser lnki_arg_parser = new Xop_lnki_arg_parser();
public Xol_func_regy Func_regy() {return func_regy;} private final Xol_func_regy func_regy;
public int Img_thumb_halign_default() {return img_thumb_halign_default;} private int img_thumb_halign_default = Xop_lnki_align_h_.Right;
@@ -119,18 +119,20 @@ public class Xol_lang_itm implements Gfo_invk {
;
private static final Hash_adp_bry fallback_dupes_regy = Hash_adp_bry.cs(); // to prevent cyclical loops during loading
public Xol_lang_itm Init_by_load_assert() {if (!loaded) Init_by_load(); return this;}
public boolean Init_by_load() {
if (this.loaded) return false;
fallback_dupes_regy.Clear();
this.loaded = true;
boolean lang_is_en = lang_id == Xol_lang_stub_.Id_en;
if (!lang_is_en) Xol_lang_itm_.Lang_init(this);
msg_mgr.Itm_by_key_or_new(Bry_.new_a7("Lang")).Atrs_set(key_bry, false, false); // set "Lang" keyword; EX: for "fr", "{{int:Lang}}" -> "fr"
Load_lang(key_bry);
ns_aliases.Ary_add_(Xow_ns_canonical_.Ary); // NOTE: always add English canonical as aliases to all languages
this.Evt_lang_changed();
return true;
public Xol_lang_itm Init_by_load() {
synchronized (thread_lock) { // Scribunto can create langs outside of wiki_lang; EX:dewiki and multiple scripts call isRTL for fr; ISSUE#:330; DATE:2019-02-09
if (!loaded) {
this.loaded = true;
fallback_dupes_regy.Clear();
boolean lang_is_en = lang_id == Xol_lang_stub_.Id_en;
if (!lang_is_en) Xol_lang_itm_.Lang_init(this);
msg_mgr.Itm_by_key_or_new(Bry_.new_a7("Lang")).Atrs_set(key_bry, false, false); // set "Lang" keyword; EX: for "fr", "{{int:Lang}}" -> "fr"
Load_lang(key_bry);
ns_aliases.Ary_add_(Xow_ns_canonical_.Ary); // NOTE: always add English canonical as aliases to all languages
this.Evt_lang_changed();
}
}
return this;
}
private void Exec_fallback_load(byte[] fallback_lang) {
Fallback_bry_(fallback_lang);

View File

@@ -45,7 +45,7 @@ public class Xobc_utl_make_lang_kwds implements Gfo_invk, Xol_lang_transform {
int hash_len = hash.Count();
for (int i = 0; i < hash_len; i++) {
Xobcl_kwd_lang cfg_lang = (Xobcl_kwd_lang)hash.Get_at(i);
Xol_lang_itm lang = lang_mgr.Get_by(cfg_lang.Key_bry()); if (lang == null) continue;
Xol_lang_itm lang = lang_mgr.Get_by_or_null(cfg_lang.Key_bry()); if (lang == null) continue;
int cfg_grp_len = cfg_lang.Grps().length;
for (int j = 0; j < cfg_grp_len; j++) {
Xobcl_kwd_row cfg_grp = cfg_lang.Grps()[j];

View File

@@ -75,7 +75,7 @@ public class Xol_mw_lang_parser {
String lang_key = String_.Replace(String_.Lower(String_.Mid(url.NameOnly(), 8)), "_", "-"); // 8=Messages.length; lower b/c format is MessagesEn.php (need "en")
// if (String_.In(lang_key, "qqq", "enrtl", "bbc", "bbc-latn")) continue;
String text = Io_mgr.Instance.LoadFilStr(url);
Xol_lang_itm lang = lang_mgr.Get_by_or_new(Bry_.new_u8(lang_key));
Xol_lang_itm lang = lang_mgr.Get_by_or_new(Bry_.new_u8(lang_key)); // NOTE: cannot be Get_by_or_load else will load from XO; actual definitions will be loaded from MW below
this.Parse_core(text, lang, bfr, lang_transform);
} catch (Exception exc) {Err_.Noop(exc); Console_adp__sys.Instance.Write_str_w_nl("failed to parse " + url.NameOnly() + Err_.Message_gplx_log(exc));}
}

View File

@@ -16,7 +16,6 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
package gplx.xowa.langs.lnki_trails; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
import gplx.core.btries.*;
public class Xol_lnki_trail_mgr implements Gfo_invk {
public Xol_lnki_trail_mgr(Xol_lang_itm lang) {}
public void Clear() {trie.Clear();}
public int Count() {return trie.Count();}
public Btrie_slim_mgr Trie() {return trie;} private final Btrie_slim_mgr trie = Btrie_slim_mgr.cs();

View File

@@ -17,22 +17,17 @@ package gplx.xowa.langs.lnki_trails; import gplx.*; import gplx.xowa.*; import g
import org.junit.*;
import gplx.xowa.langs.names.*;
public class Xol_lnki_trail_mgr_tst {
@Before public void init() {fxt.Clear();} private Xol_lnki_trail_mgr_fxt fxt = new Xol_lnki_trail_mgr_fxt();
private final Xol_lnki_trail_mgr_fxt fxt = new Xol_lnki_trail_mgr_fxt();
@Test public void Add_bulk() {
fxt.Test_add_bulk("äöüß", "ä", "ö", "ü", "ß");
}
}
class Xol_lnki_trail_mgr_fxt {
Xol_lang_itm lang; Xol_lnki_trail_mgr lnki_trail_mgr;
public void Clear() {
Xoae_app app = Xoa_app_fxt.Make__app__edit();
lang = Xol_lang_itm.New(app.Lang_mgr(), Bry_.new_a7("fr"));
lnki_trail_mgr = lang.Lnki_trail_mgr();
}
private final Xol_lnki_trail_mgr lnki_trail_mgr = new Xol_lnki_trail_mgr();
public void Test_add_bulk(String raw, String... expd_ary) {
lnki_trail_mgr.Add_bulk(Bry_.new_u8(raw));
int expd_len = expd_ary.length;
Tfds.Eq(expd_len, lang.Lnki_trail_mgr().Count());
Tfds.Eq(expd_len, lnki_trail_mgr.Count());
for (int i = 0; i < expd_len; i++) {
byte[] expd_bry = Bry_.new_u8(expd_ary[i]);
byte[] actl_bry = (byte[])lnki_trail_mgr.Trie().Match_bgn(expd_bry, 0, expd_bry.length);

View File

@@ -148,7 +148,7 @@ public class Xol_msg_mgr_ {
Xoa_lang_mgr lang_mgr = wiki.App().Lang_mgr();
for (int i = 0; i < fallback_ary_len; i++) {
byte[] fallback = fallback_ary[i];
Xol_lang_itm fallback_lang = lang_mgr.Get_by(fallback);
Xol_lang_itm fallback_lang = lang_mgr.Get_by_or_null(fallback);
if (fallback_lang == null) continue; // NOTE: en has fallback of "false"; ignore bad fallbacks;
rv = fallback_lang.Msg_mgr().Itm_by_key_or_null(msg_key_sub_root);
if (rv != null) break;

View File

@@ -165,8 +165,7 @@ public class Xol_lang_srl_tst {
@Test public void Fallback_circular() { // PURPOSE: pt and pt-br cite each other as fallback in Messages*.php; DATE:2013-02-18
Io_mgr.Instance.SaveFilStr(Xol_lang_itm_.xo_lang_fil_(fxt.App().Fsys_mgr(), "pt") , "fallback_load('pt-br');");
Io_mgr.Instance.SaveFilStr(Xol_lang_itm_.xo_lang_fil_(fxt.App().Fsys_mgr(), "pt-br") , "fallback_load('pt');");
Xol_lang_itm lang = Xol_lang_itm.New(fxt.App().Lang_mgr(), Bry_.new_a7("pt"));
lang.Init_by_load();
fxt.App().Lang_mgr().Get_by_or_load(Bry_.new_a7("pt")); // fails if test-suite gets stuck
}
@Test public void Num_fmt() {
String raw = String_.Concat_lines_nl
@@ -203,7 +202,7 @@ class Xol_lang_srl_fxt {
app = Xoa_app_fxt.Make__app__edit();
lang = Xol_lang_itm.New(app.Lang_mgr(), Bry_.new_a7("fr"));
Xoa_gfs_mgr.Msg_parser_init(); // required by fallback_load
} GfsCtx ctx = GfsCtx.new_(); Xoa_gfs_bldr bldr = new Xoa_gfs_bldr(); //Bry_bfr tmp_bfr = Bry_bfr_.Reset(255);
} GfsCtx ctx = GfsCtx.new_(); Xoa_gfs_bldr bldr = new Xoa_gfs_bldr();
public Xoae_app App() {return app;} private Xoae_app app;
public Xol_lang_itm Lang() {return lang;} private Xol_lang_itm lang;
public Xow_ns ns_(int id, String s) {return new Xow_ns(id, Xow_ns_case_.Tid__1st, Bry_.new_u8(s), false);}