mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
Wikibase: Add getReferencedEntityId; refactor some wikibase code
This commit is contained in:
parent
6348aa6177
commit
341d2e13a4
@ -15,8 +15,8 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.apps.caches; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*;
|
||||
import gplx.xowa.xtns.wbases.*;
|
||||
public class Wdata_doc_cache {
|
||||
private Hash_adp_bry hash = Hash_adp_bry.cs();
|
||||
public class Wbase_doc_cache {
|
||||
private final Hash_adp_bry hash = Hash_adp_bry.cs();
|
||||
public void Add(byte[] qid, Wdata_doc doc) {hash.Add(qid, doc);}
|
||||
public Wdata_doc Get_or_null(byte[] qid) {return (Wdata_doc)hash.Get_by_bry(qid);}
|
||||
public void Free_mem_all() {this.Clear();}
|
@ -15,7 +15,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.apps.caches; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*;
|
||||
public class Xoa_cache_mgr {
|
||||
public Wdata_doc_cache Doc_cache() {return doc_cache;} private Wdata_doc_cache doc_cache = new Wdata_doc_cache();
|
||||
public Wbase_doc_cache Doc_cache() {return doc_cache;} private Wbase_doc_cache doc_cache = new Wbase_doc_cache();
|
||||
public void Free_mem_all() {
|
||||
doc_cache.Free_mem_all();
|
||||
}
|
||||
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.xtns.scribunto.libs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
|
||||
import gplx.xowa.xtns.wbases.*; import gplx.xowa.xtns.wbases.claims.*; import gplx.xowa.xtns.wbases.claims.itms.*; import gplx.xowa.xtns.wbases.claims.enums.*;
|
||||
// REF: https://github.com/wmde/WikibaseDataModelServices/blob/master/src/Lookup/EntityRetrievingClosestReferencedEntityIdLookup.php
|
||||
class Referenced_entity_lookup_wkr {
|
||||
private final Wbase_doc_mgr entity_mgr;
|
||||
private final int maxDepth;
|
||||
private final int maxEntityVisits;
|
||||
private final Xoa_url url;
|
||||
private final byte[] fromId;
|
||||
private final int propertyId;
|
||||
private final Ordered_hash toIds;
|
||||
private final Ordered_hash alreadyVisited = Ordered_hash_.New_bry();
|
||||
private final List_adp tmp_snak_list = List_adp_.New();
|
||||
public Referenced_entity_lookup_wkr(int maxDepth, int maxEntityVisits, Wbase_doc_mgr entity_mgr, Xoa_url url, byte[] fromId, int propertyId, Ordered_hash toIds) {
|
||||
this.maxDepth = maxDepth;
|
||||
this.maxEntityVisits = maxEntityVisits;
|
||||
this.entity_mgr = entity_mgr;
|
||||
this.url = url;
|
||||
this.fromId = fromId;
|
||||
this.propertyId = propertyId;
|
||||
this.toIds = toIds;
|
||||
}
|
||||
public byte[] Get_referenced_entity() {
|
||||
if (toIds == null)
|
||||
return null;
|
||||
|
||||
int steps = this.maxDepth + 1;// Add one as checking $fromId already is a step
|
||||
Ordered_hash toVisit = Ordered_hash_.New_bry();
|
||||
toVisit.Add_as_key_and_val(fromId);
|
||||
|
||||
while (steps-- > 0) {
|
||||
// $this->entityPrefetcher->prefetch( $toVisit );
|
||||
Ordered_hash toVisitNext = Ordered_hash_.New_bry();
|
||||
int toVisitLen = toVisit.Len();
|
||||
for (int i = 0; i < toVisitLen; i++) {
|
||||
byte[] curId = (byte[])toVisit.Get_at(i);
|
||||
byte[] result = processEntityById(alreadyVisited, curId, fromId, propertyId, toIds, toVisitNext);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
// Remove already visited entities
|
||||
toVisit = merge(toVisitNext, alreadyVisited);
|
||||
if (toVisit.Len() == 0)
|
||||
return null;
|
||||
}
|
||||
// Exhausted the max. depth without finding anything.
|
||||
throw newErr(true);
|
||||
}
|
||||
private Err newErr(boolean isMaxDepthOrMaxEntities) {
|
||||
return Err_.new_wo_type("max exceeded", "type", isMaxDepthOrMaxEntities ? "depth" : "entities", "url", url.To_bry(true, false), "fromId", fromId, "propertyId", propertyId, "toIds", toString(toIds));
|
||||
}
|
||||
private static String toString(Ordered_hash hash) {
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
int len = hash.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
bfr.Add_str_u8(Object_.Xto_str_strict_or_null_mark(hash.Get_at(i))).Add_byte_pipe();
|
||||
}
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
private byte[] processEntityById(Ordered_hash alreadyVisited, byte[] id, byte[] fromId, int propertyId, Ordered_hash toIds, Ordered_hash toVisit) {
|
||||
Wdata_doc entity = getEntity(alreadyVisited, id, fromId, propertyId, toIds);
|
||||
if (entity == null)
|
||||
return null;
|
||||
Wbase_claim_base[] mainSnaks = getMainSnaks(entity, propertyId);
|
||||
for (Wbase_claim_base mainSnak : mainSnaks) {
|
||||
byte[] result = processSnak(mainSnak, toVisit, toIds);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private Wdata_doc getEntity(Ordered_hash alreadyVisited, byte[] id, byte[] fromId, int propertyId, Ordered_hash toIds) {
|
||||
if (alreadyVisited.Has(id)) {
|
||||
Gfo_usr_dlg_.Instance.Warn_many("", "", "Entity " + String_.new_u8(id) + " already visited");
|
||||
return null;
|
||||
}
|
||||
alreadyVisited.Add_as_key_and_val(id);
|
||||
if (alreadyVisited.Len() > maxEntityVisits)
|
||||
throw newErr(false);
|
||||
return entity_mgr.Get_by_bry_or_null(id);
|
||||
}
|
||||
private Wbase_claim_base[] getMainSnaks(Wdata_doc entity, int propertyId) {
|
||||
Wbase_claim_grp claims = entity.Claim_list_get(propertyId);
|
||||
return claims.Get_best(tmp_snak_list);
|
||||
}
|
||||
private byte[] processSnak(Wbase_claim_base snak, Ordered_hash toVisit, Ordered_hash toIds) {
|
||||
if (snak.Val_tid() != Wbase_claim_type_.Tid__entity)
|
||||
return null;
|
||||
Wbase_claim_entity snakEntity = (Wbase_claim_entity)snak;
|
||||
byte[] entityId = snakEntity.Page_ttl_db();
|
||||
if (toIds.Has(entityId))
|
||||
return entityId;
|
||||
toVisit.Add_as_key_and_val(entityId);
|
||||
return null;
|
||||
}
|
||||
|
||||
private Ordered_hash merge(Ordered_hash toVisitNext, Ordered_hash alreadyVisited) {
|
||||
int len = alreadyVisited.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
byte[] bry = (byte[])alreadyVisited.Get_at(i);
|
||||
if (toVisitNext.Has(bry))
|
||||
toVisitNext.Del(bry);
|
||||
}
|
||||
return toVisitNext;
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import gplx.xowa.xtns.scribunto.procs.*;
|
||||
import gplx.xowa.xtns.wbases.mediawiki.client.includes.*; import gplx.xowa.xtns.wbases.mediawiki.client.includes.dataAccess.scribunto.*;
|
||||
public class Scrib_lib_wikibase implements Scrib_lib {
|
||||
private final Scrib_core core;
|
||||
private Wbase_doc_mgr entity_mgr;
|
||||
private Wbase_entity_accessor entity_accessor;
|
||||
private WikibaseLanguageIndependentLuaBindings wikibaseLanguageIndependentLuaBindings;
|
||||
private Scrib_lua_proc notify_page_changed_fnc;
|
||||
@ -28,9 +29,9 @@ public class Scrib_lib_wikibase implements Scrib_lib {
|
||||
public Scrib_proc_mgr Procs() {return procs;} private final Scrib_proc_mgr procs = new Scrib_proc_mgr();
|
||||
public Scrib_lib Init() {
|
||||
procs.Init_by_lib(this, Proc_names);
|
||||
Wbase_doc_mgr entityMgr = core.App().Wiki_mgr().Wdata_mgr().Doc_mgr;
|
||||
this.entity_accessor = new Wbase_entity_accessor(entityMgr);
|
||||
this.wikibaseLanguageIndependentLuaBindings = new WikibaseLanguageIndependentLuaBindings(entityMgr);
|
||||
this.entity_mgr = core.App().Wiki_mgr().Wdata_mgr().Doc_mgr;
|
||||
this.entity_accessor = new Wbase_entity_accessor(entity_mgr);
|
||||
this.wikibaseLanguageIndependentLuaBindings = new WikibaseLanguageIndependentLuaBindings(entity_mgr);
|
||||
return this;
|
||||
}
|
||||
public Scrib_lib Clone_lib(Scrib_core core) {return new Scrib_lib_wikibase(core);}
|
||||
@ -97,11 +98,14 @@ public class Scrib_lib_wikibase implements Scrib_lib {
|
||||
entityId = Bry_.Mid(entityId, colonPos + 1);
|
||||
}
|
||||
|
||||
boolean valid = checkEntityIdOrNull(entityId) != null;
|
||||
return rslt.Init_obj(valid);
|
||||
}
|
||||
private static byte[] checkEntityIdOrNull(byte[] entityId) {
|
||||
/* REF: https://github.com/wmde/WikibaseDataModel/tree/master/src/Entity/
|
||||
PropertyId.php.PATTERN: '/^P[1-9]\d{0,9}\z/i';
|
||||
ItemId.php.PATTERN : '/^Q[1-9]\d{0,9}\z/i';
|
||||
*/
|
||||
boolean valid = false;
|
||||
if (entityId.length > 0) {
|
||||
switch (entityId[0]) {
|
||||
case Byte_ascii.Ltr_P:
|
||||
@ -122,14 +126,14 @@ public class Scrib_lib_wikibase implements Scrib_lib {
|
||||
}
|
||||
}
|
||||
if (numeric)
|
||||
valid = true;
|
||||
return entityId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rslt.Init_obj(valid);
|
||||
return null;
|
||||
}
|
||||
public boolean GetEntityId(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
byte[] ttl_bry = args.Pull_bry(0);
|
||||
@ -138,8 +142,21 @@ public class Scrib_lib_wikibase implements Scrib_lib {
|
||||
byte[] rv = wiki.Appe().Wiki_mgr().Wdata_mgr().Qid_mgr.Get_or_null(wiki, ttl); if (rv == null) rv = Bry_.Empty;
|
||||
return rslt.Init_obj(rv);
|
||||
}
|
||||
// REF: https://github.com/wikimedia/mediawiki-extensions-Wikibase/blob/master/client/config/WikibaseClient.default.php
|
||||
private static final int ReferencedEntityIdMaxDepth = 4, ReferencedEntityIdMaxReferencedEntityVisits = 50;
|
||||
// private static final int ReferencedEntityIdAccessLimit = 3; // max # of calls per page?
|
||||
public boolean GetReferencedEntityId(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
throw Err_.new_unimplemented();
|
||||
// get fromId, propertyId, and toIds
|
||||
byte[] fromId = checkEntityIdOrNull(args.Pull_bry(0));
|
||||
byte[] propertyIdBry = checkEntityIdOrNull(args.Pull_bry(1));
|
||||
int propertyId = Bry_.To_int(Bry_.Mid(propertyIdBry, 1));
|
||||
Keyval[] toIdsAry = args.Pull_kv_ary_safe(2);
|
||||
Ordered_hash toIds = Ordered_hash_.New_bry();
|
||||
for (Keyval kv : toIdsAry) {
|
||||
toIds.Add_as_key_and_val(checkEntityIdOrNull(Bry_.new_u8((String)kv.Val())));
|
||||
}
|
||||
Referenced_entity_lookup_wkr wkr = new Referenced_entity_lookup_wkr(ReferencedEntityIdMaxDepth, ReferencedEntityIdMaxReferencedEntityVisits, entity_mgr, core.Page().Url(), fromId, propertyId, toIds);
|
||||
return rslt.Init_obj(wkr.Get_referenced_entity());
|
||||
}
|
||||
public boolean EntityExists(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
Wdata_doc wdoc = Get_wdoc_or_null(args, core, false);
|
||||
@ -238,12 +255,12 @@ public function formatValues( $snaksSerialization ) {
|
||||
public boolean IncrementExpensiveFunctionCount(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
return rslt.Init_obj(Keyval_.Ary_empty); // NOTE: for now, always return null (XOWA does not care about expensive parser functions)
|
||||
}
|
||||
private static Wdata_doc Get_wdoc_or_null(Scrib_proc_args args, Scrib_core core, boolean logMissing) {
|
||||
public Wdata_doc Get_wdoc_or_null(Scrib_proc_args args, Scrib_core core, boolean logMissing) {
|
||||
// get qid / pid from scrib_arg[0]; if none, return null;
|
||||
byte[] xid_bry = args.Pull_bry(0); if (Bry_.Len_eq_0(xid_bry)) return null; // NOTE: some Modules do not pass in an argument; return early, else spurious warning "invalid qid for ttl" (since ttl is blank); EX:w:Module:Authority_control; DATE:2013-10-27
|
||||
|
||||
// get wdoc
|
||||
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"
|
||||
Wdata_doc wdoc = entity_mgr.Get_by_xid_or_null(xid_bry); // NOTE: by_xid b/c Module passes just "p1" not "Property:P1"
|
||||
if (wdoc == null && logMissing) Wdata_wiki_mgr.Log_missing_qid(core.Ctx(), xid_bry);
|
||||
return wdoc;
|
||||
}
|
||||
|
@ -54,6 +54,21 @@ public class Scrib_lib_wikibase_tst {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_wikibase.Invk_getEntityId, Object_.Ary("Earth" ), "q2");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_wikibase.Invk_getEntityId, Object_.Ary("missing_page" ), "");
|
||||
}
|
||||
@Test public void GetReferencedEntityId() {
|
||||
/*
|
||||
wdata_fxt.Init__docs__add(wdata_fxt.Wdoc_bldr("q1").Xto_wdoc());
|
||||
wdata_fxt.Init__docs__add(wdata_fxt.Wdoc_bldr("q2").Add_claims(wdata_fxt.Make_claim_entity_qid(1, 1)).Xto_wdoc());
|
||||
wdata_fxt.Init__docs__add(wdata_fxt.Wdoc_bldr("q3").Add_claims(wdata_fxt.Make_claim_entity_qid(1, 2)).Xto_wdoc());
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_wikibase.Invk_getReferencedEntityId, Object_.Ary("Q3", "P1", NewToIds("Q1")), "Q1");
|
||||
*/
|
||||
}
|
||||
private static Keyval[] NewToIds(String... toIds) {
|
||||
int len = toIds.length;
|
||||
Keyval[] rv = new Keyval[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
rv[i] = Keyval_.int_(i, toIds[i]);
|
||||
return rv;
|
||||
}
|
||||
@Test public void GetLabel__cur() {
|
||||
wdata_fxt.Init__docs__add(wdata_fxt.Wdoc_bldr("q2").Add_label("zh-hans", "s").Add_label("zh-hant", "t").Xto_wdoc());
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_wikibase.Invk_getLabel, Object_.Ary("q2"), "s"); // do not get fallback
|
||||
|
@ -16,25 +16,26 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
package gplx.xowa.xtns.wbases; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.langs.jsons.*;
|
||||
import gplx.xowa.wikis.pages.*;
|
||||
import gplx.xowa.apps.caches.*;
|
||||
public class Wbase_doc_mgr {
|
||||
private final Xoae_app app;
|
||||
private final Wdata_wiki_mgr wbase_mgr;
|
||||
private final Wbase_qid_mgr qid_mgr;
|
||||
private final gplx.xowa.apps.caches.Wdata_doc_cache hash;
|
||||
private final Wbase_doc_cache doc_cache;
|
||||
public Wbase_doc_mgr(Xoae_app app, Wdata_wiki_mgr wbase_mgr, Wbase_qid_mgr qid_mgr) {
|
||||
this.app = app; this.wbase_mgr = wbase_mgr; this.qid_mgr = qid_mgr;
|
||||
this.hash = app.Cache_mgr().Doc_cache();
|
||||
this.doc_cache = app.Cache_mgr().Doc_cache();
|
||||
}
|
||||
public void Enabled_(boolean v) {this.enabled = v;} private boolean enabled;
|
||||
public void Clear() {
|
||||
synchronized (hash) { // LOCK:app-level
|
||||
hash.Clear();
|
||||
synchronized (doc_cache) { // LOCK:app-level
|
||||
doc_cache.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);
|
||||
synchronized (doc_cache) { // LOCK:app-level
|
||||
if (doc_cache.Get_or_null(full_db) == null)
|
||||
doc_cache.Add(full_db, page);
|
||||
}
|
||||
}
|
||||
public Wdata_doc Get_by_ttl_or_null(Xowe_wiki wiki, Xoa_ttl ttl) {
|
||||
@ -43,18 +44,18 @@ public class Wbase_doc_mgr {
|
||||
}
|
||||
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[] ttl_bry) {// must be correct format; EX:"Q2" or "Property:P1"
|
||||
Wdata_doc rv = hash.Get_or_null(ttl_bry);
|
||||
Wdata_doc rv = doc_cache.Get_or_null(ttl_bry);
|
||||
if (rv == null) {
|
||||
synchronized (hash) { // LOCK:app-level; hash;
|
||||
synchronized (doc_cache) { // LOCK:app-level; doc_cache;
|
||||
rv = Load_wdoc_or_null(ttl_bry); if (rv == null) return null; // page not found
|
||||
Add(ttl_bry, rv);// NOTE: use ttl_bry, not rv.Qid; allows subsequent lookups to skip this redirect cycle
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public Wdata_doc Load_wdoc_or_null(byte[] src_ttl_bry) {
|
||||
private Wdata_doc Load_wdoc_or_null(byte[] src_ttl_bry) {
|
||||
if (!enabled) return null;
|
||||
synchronized (hash) { // LOCK:app-level; jdoc_parser; moved synchronized higher up; DATE:2016-09-03
|
||||
synchronized (doc_cache) { // LOCK:app-level; jdoc_parser; moved synchronized higher up; DATE:2016-09-03
|
||||
byte[] cur_ttl_bry = src_ttl_bry;
|
||||
int load_count = -1;
|
||||
while (load_count < 2) { // limit to 2 tries (i.e.: 1 redirect)
|
||||
|
@ -25,7 +25,7 @@ public class Wbase_doc_mgr__tst {
|
||||
fxt.Parser_fxt().Init_page_create(wbase_mgr.Wdata_wiki(), "Q2", Json_doc.Make_str_by_apos("{'entity':'q2','links':{'enwiki':'q2_en','dewiki':'q2_de'}}"));
|
||||
|
||||
// fetch Q1; assert Q2 comes back
|
||||
Wdata_doc actl = wbase_mgr.Doc_mgr.Load_wdoc_or_null(Bry_.new_u8("Q1"));
|
||||
Wdata_doc actl = wbase_mgr.Doc_mgr.Get_by_bry_or_null(Bry_.new_u8("Q1"));
|
||||
Gftest.Eq__str("Q2", String_.new_u8(actl.Qid()));
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.xtns.wbases.claims; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.wbases.*;
|
||||
import gplx.core.primitives.*;
|
||||
import gplx.xowa.xtns.wbases.claims.itms.*;
|
||||
import gplx.xowa.xtns.wbases.claims.enums.*; import gplx.xowa.xtns.wbases.claims.itms.*;
|
||||
public class Wbase_claim_grp {
|
||||
public Wbase_claim_grp(Int_obj_ref id_ref, Wbase_claim_base[] itms) {this.id_ref = id_ref; this.itms = itms;}
|
||||
public Int_obj_ref Id_ref() {return id_ref;} private final Int_obj_ref id_ref;
|
||||
@ -23,6 +23,36 @@ public class Wbase_claim_grp {
|
||||
public String Id_str() {if (id_str == null) id_str = "P" + Int_.To_str(id_ref.Val()); return id_str;} private String id_str;
|
||||
public int Len() {return itms.length;} private Wbase_claim_base[] itms;
|
||||
public Wbase_claim_base Get_at(int i) {return itms[i];}
|
||||
|
||||
/*
|
||||
Returns the so called "best statements".
|
||||
If there are preferred statements, then this is all the preferred statements.
|
||||
If there are no preferred statements, then this is all normal statements.
|
||||
*/
|
||||
public Wbase_claim_base[] Get_best(List_adp tmp_snak_list) {
|
||||
int len = itms.length;
|
||||
boolean preferred_found = false;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Wbase_claim_base itm = itms[i];
|
||||
switch (itm.Rank_tid()) {
|
||||
case Wbase_claim_rank_.Tid__preferred:
|
||||
if (!preferred_found) {
|
||||
if (tmp_snak_list.Len() > 0)
|
||||
tmp_snak_list.Clear();
|
||||
preferred_found = true;
|
||||
}
|
||||
tmp_snak_list.Add(itm);
|
||||
break;
|
||||
case Wbase_claim_rank_.Tid__normal:
|
||||
if (!preferred_found)
|
||||
tmp_snak_list.Add(itm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return tmp_snak_list.Count() == 0 ? Empty_array : (Wbase_claim_base[])tmp_snak_list.To_ary_and_clear(Wbase_claim_base.class);
|
||||
}
|
||||
private static final Wbase_claim_base[] Empty_array = new Wbase_claim_base[0];
|
||||
|
||||
public static List_adp Xto_list(Ordered_hash hash) {
|
||||
int len = hash.Count();
|
||||
List_adp rv = List_adp_.New();
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.xtns.wbases.claims; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.wbases.*;
|
||||
import org.junit.*; import gplx.core.tests.*; import gplx.core.primitives.*;
|
||||
import gplx.xowa.xtns.wbases.claims.enums.*; import gplx.xowa.xtns.wbases.claims.itms.*;
|
||||
public class Wbase_claim_grp_tst {
|
||||
@Test public void Get_best__preferred() {
|
||||
Wbase_claim_grp_bldr bldr = new Wbase_claim_grp_bldr(123);
|
||||
bldr.Add("P1", Wbase_claim_rank_.Tid__preferred);
|
||||
bldr.Add("N1", Wbase_claim_rank_.Tid__normal);
|
||||
bldr.Add("P2", Wbase_claim_rank_.Tid__preferred);
|
||||
bldr.Add("N2", Wbase_claim_rank_.Tid__normal);
|
||||
bldr.Test__Get_best("P1", "P2");
|
||||
}
|
||||
@Test public void Get_best__normal_if_no_preferred() {
|
||||
Wbase_claim_grp_bldr bldr = new Wbase_claim_grp_bldr(123);
|
||||
bldr.Add("D1", Wbase_claim_rank_.Tid__deprecated);
|
||||
bldr.Add("D2", Wbase_claim_rank_.Tid__deprecated);
|
||||
bldr.Add("N1", Wbase_claim_rank_.Tid__normal);
|
||||
bldr.Add("N2", Wbase_claim_rank_.Tid__normal);
|
||||
bldr.Test__Get_best("N1", "N2");
|
||||
}
|
||||
@Test public void Get_best__preferred_after_normal() {
|
||||
Wbase_claim_grp_bldr bldr = new Wbase_claim_grp_bldr(123);
|
||||
bldr.Add("N1", Wbase_claim_rank_.Tid__normal);
|
||||
bldr.Add("N2", Wbase_claim_rank_.Tid__normal);
|
||||
bldr.Add("P1", Wbase_claim_rank_.Tid__preferred);
|
||||
bldr.Add("P2", Wbase_claim_rank_.Tid__preferred);
|
||||
bldr.Test__Get_best("P1", "P2");
|
||||
}
|
||||
}
|
||||
class Wbase_claim_grp_bldr {
|
||||
private final int pid;
|
||||
private final List_adp list = List_adp_.New();
|
||||
public Wbase_claim_grp_bldr(int pid) {
|
||||
this.pid = pid;
|
||||
}
|
||||
public void Add(String val, byte rank_tid) {
|
||||
Wbase_claim_string claim = new Wbase_claim_string(pid, Wbase_claim_value_type_.Tid__value, Bry_.new_u8(val));
|
||||
claim.Rank_tid_(rank_tid);
|
||||
list.Add(claim);
|
||||
}
|
||||
public void Test__Get_best(String... expd) {
|
||||
Wbase_claim_grp grp = new Wbase_claim_grp(Int_obj_ref.New(pid), (Wbase_claim_base[])list.To_ary_and_clear(Wbase_claim_base.class));
|
||||
|
||||
List_adp tmp_list = List_adp_.New();
|
||||
Gftest.Eq__ary(expd, To_string(grp.Get_best(tmp_list)));
|
||||
}
|
||||
private String[] To_string(Wbase_claim_base[] items) {
|
||||
int len = items.length;
|
||||
String[] rv = new String[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
Wbase_claim_string claim = (Wbase_claim_string)items[i];
|
||||
rv[i] = String_.new_u8(claim.Val_bry());
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user