Wikibase: Do not fail for FormatStatements and getPropertyOrder [#658]

staging
gnosygnu 4 years ago
parent bc2beba148
commit 775bff3bac

@ -33,6 +33,9 @@ public class Bitmask_ {
}
return rv;
}
public static int Set_or_add(int val, int flag) {
return val == 0 ? flag : val | flag;
}
public static boolean Has_byte(byte val, byte find) {return find == (val & find);}
public static byte Add_byte(byte flag, byte itm) {return (byte)(flag | itm);}
}

@ -37,8 +37,9 @@ public interface String_bldr {
String_bldr Add(char c);
String_bldr Add(int i);
String_bldr Add_obj(Object o);
String_bldr Add_mid(char[] ary, int bgn, int count);
String_bldr Add_mid(String str, int bgn, int count);
String_bldr Add_mid(String str, int bgn, int end);
String_bldr Add_mid_len(char[] ary, int bgn, int count);
String_bldr Add_mid_len(String str, int bgn, int count);
String_bldr Add_at(int idx, String s);
String_bldr Del(int bgn, int len);
}
@ -83,8 +84,9 @@ abstract class String_bldr_base implements String_bldr {
public abstract String_bldr Add(String s);
public abstract String_bldr Add(char c);
public abstract String_bldr Add(int i);
public abstract String_bldr Add_mid(char[] ary, int bgn, int count);
public abstract String_bldr Add_mid(String str, int bgn, int count);
public abstract String_bldr Add_mid(String str, int bgn, int end);
public abstract String_bldr Add_mid_len(char[] ary, int bgn, int count);
public abstract String_bldr Add_mid_len(String str, int bgn, int count);
public abstract String_bldr Add_obj(Object o);
public abstract String_bldr Del(int bgn, int len);
}
@ -97,8 +99,9 @@ class String_bldr_thread_single extends String_bldr_base {
@Override public String_bldr Add(String s) {sb.append(s); return this;}
@Override public String_bldr Add(char c) {sb.append(c); return this;}
@Override public String_bldr Add(int i) {sb.append(i); return this;}
@Override public String_bldr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
@Override public String_bldr Add_mid(String str, int bgn, int count) {sb.append(str, bgn, count); return this;}
@Override public String_bldr Add_mid(String str, int bgn, int end) {sb.append(str, bgn, end); return this;}
@Override public String_bldr Add_mid_len(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
@Override public String_bldr Add_mid_len(String str, int bgn, int count) {sb.append(str, bgn, count); return this;}
@Override public String_bldr Add_obj(Object o) {sb.append(o); return this;}
@Override public String_bldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
}
@ -111,8 +114,9 @@ class String_bldr_thread_multiple extends String_bldr_base {
@Override public String_bldr Add(String s) {sb.append(s); return this;}
@Override public String_bldr Add(char c) {sb.append(c); return this;}
@Override public String_bldr Add(int i) {sb.append(i); return this;}
@Override public String_bldr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
@Override public String_bldr Add_mid(String str, int bgn, int count) {sb.append(str, bgn, count); return this;}
@Override public String_bldr Add_mid(String str, int bgn, int end) {sb.append(str, bgn, end); return this;}
@Override public String_bldr Add_mid_len(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
@Override public String_bldr Add_mid_len(String str, int bgn, int count) {sb.append(str, bgn, count); return this;}
@Override public String_bldr Add_obj(Object o) {sb.append(o); return this;}
@Override public String_bldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
}

@ -17,7 +17,10 @@ package gplx.langs.regxs; import gplx.*; import gplx.langs.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Regx_adp {
@gplx.Internal protected Regx_adp(String regx) {Pattern_(regx);}
public Regx_adp(String regx, int flags) {
this.flags = flags;
Pattern_(regx);
}
public String Pattern() {return pattern;} public Regx_adp Pattern_(String val) {pattern = val; Under_sync(); return this;} private String pattern;
public boolean Pattern_is_invalid() {return pattern_is_invalid;} private boolean pattern_is_invalid = false;
public Exception Pattern_is_invalid_exception() {return pattern_is_invalid_exception;} private Exception pattern_is_invalid_exception = null;
@ -38,14 +41,15 @@ public class Regx_adp {
}
return (Regx_match[])rv.To_ary(Regx_match.class);
}
private Pattern under;
private int flags = FLAG__DOTALL | FLAG__UNICODE_CHARACTER_CLASS;// JRE.7:UNICODE_CHARACTER_CLASS; added during %w fix for en.w:A#; DATE:2015-06-10
private Pattern under;
public Pattern Under() {return under;}
private void Under_sync() {
try {under = Pattern.compile(pattern, Pattern.DOTALL | Pattern.UNICODE_CHARACTER_CLASS);} // JRE.7:UNICODE_CHARACTER_CLASS; added during %w fix for en.w:A#; DATE:2015-06-10
try {under = Pattern.compile(pattern, flags);}
catch (Exception e) { // NOTE: if invalid, then default to empty pattern (which should return nothing); EX:d:〆る generates [^]; DATE:2013-10-20
pattern_is_invalid = true;
pattern_is_invalid_exception = e;
under = Pattern.compile("", Pattern.DOTALL | Pattern.UNICODE_CHARACTER_CLASS);
under = Pattern.compile("", flags);
}
}
public Regx_match Match(String input, int bgn) {
@ -67,4 +71,18 @@ public class Regx_adp {
return new Regx_match(success, match_bgn, match_end, ary);
}
public String ReplaceAll(String input, String replace) {return under.matcher(input).replaceAll(replace);}
// https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
public static final int
FLAG__NONE = 0
, FLAG__UNIX_LINES = Pattern.UNIX_LINES
, FLAG__CASE_INSENSITIVE = Pattern.CASE_INSENSITIVE
, FLAG__COMMENTS = Pattern.COMMENTS
, FLAG__MULTILINE = Pattern.MULTILINE
, FLAG__LITERAL = Pattern.LITERAL
, FLAG__DOTALL = Pattern.DOTALL
, FLAG__UNICODE_CASE = Pattern.UNICODE_CASE
, FLAG__CANON_EQ = Pattern.CANON_EQ
, FLAG__UNICODE_CHARACTER_CLASS = Pattern.UNICODE_CHARACTER_CLASS
;
public static final int FLAG__DEFAULT = FLAG__DOTALL | FLAG__UNICODE_CHARACTER_CLASS;// JRE.7:UNICODE_CHARACTER_CLASS; added during %w fix for en.w:A#; DATE:2015-06-10
}

@ -15,7 +15,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.regxs; import gplx.*; import gplx.langs.*;
public class Regx_adp_ {
public static Regx_adp new_(String pattern) {return new Regx_adp(pattern);}
public static Regx_adp new_(String pattern) {return new Regx_adp(pattern, Regx_adp.FLAG__DEFAULT);}
public static List_adp Find_all(String src, String pat) {
int src_len = String_.Len(src);
Regx_adp regx = Regx_adp_.new_(pat);
@ -34,7 +34,7 @@ public class Regx_adp_ {
return regx.ReplaceAll(raw, replace);
}
public static boolean Match(String input, String pattern) {
Regx_adp rv = new Regx_adp(pattern);
Regx_adp rv = new Regx_adp(pattern, Regx_adp.FLAG__DEFAULT);
return rv.Match(input, 0).Rslt();
}
}

@ -26,6 +26,7 @@ public class Regx_match {
public int Find_bgn() {return find_bgn;} private final int find_bgn;
public int Find_end() {return find_end;} private final int find_end;
public int Find_len() {return find_end - find_bgn;}
public String Find_str(String s) {return String_.Mid(s, find_bgn, find_end);}
public Regx_group[] Groups() {return groups;} private final Regx_group[] groups;
public static final Regx_match[] Ary_empty = new Regx_match[0];

@ -80,7 +80,7 @@ class GfmlLxr_group implements GfmlLxr {
public GfmlTkn MakeTkn(CharStream stream, int hookLength) {
while (stream.AtMid()) {
if (!ignoreOutput)
sb.Add_mid(stream.Ary(), stream.Pos(), hookLength);
sb.Add_mid_len(stream.Ary(), stream.Pos(), hookLength);
stream.MoveNextBy(hookLength);
String found = String_.cast(trie.FindMatch(stream));

@ -142,4 +142,26 @@ public class XophpArray_ {
return true;
return false;
}
// REF.PHP:https://www.php.net/manual/en/function.array-map.php
public static XophpArray array_map(XophpCallbackOwner callback_owner, String method, XophpArray array) {
XophpArray rv = XophpArray.New();
int len = array.count();
for (int i = 0; i < len; i++) {
String itm = array.Get_at_str(i);
rv.Add((String)callback_owner.Callback(method, itm));
}
return rv;
}
// REF.PHP:https://www.php.net/manual/en/function.array-flip.php
public static XophpArray array_flip(XophpArray array) {
XophpArray rv = XophpArray.New();
int len = array.count();
for (int i = 0; i < len; i++) {
XophpArrayItm itm = array.Get_at_itm(i);
rv.Set(Object_.Xto_str_strict_or_null(itm.Val()), itm.Key());
}
return rv;
}
}

@ -222,6 +222,27 @@ public class XophpArray__tst { // REF:https://www.php.net/manual/en/function.arr
, orig.values()
);
}
@Test public void array_map() {
XophpArray orig = fxt.Make().Add_many("a", "b", "c");
fxt.Test__eq
( fxt.Make().Add_many("A", "B", "C")
, XophpArray_.array_map(XophpString_.Callback_owner, "strtoupper", orig)
);
}
@Test public void array_flip__basic() {
XophpArray orig = fxt.Make().Add_many("oranges", "apples", "pears");
fxt.Test__eq
( fxt.Make().Add("oranges", 0).Add("apples", 1).Add("pears", 2)
, XophpArray_.array_flip(orig)
);
}
@Test public void array_flip__collision() {
XophpArray orig = fxt.Make().Add("a", 1).Add("b", 1).Add("c", 2);
fxt.Test__eq
( fxt.Make().Add("1", "b").Add("2", "c")
, XophpArray_.array_flip(orig)
);
}
}
class XophpArray__fxt {
public XophpArray Make() {return new XophpArray();}

@ -0,0 +1,19 @@
/*
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.mediawiki; import gplx.*; import gplx.xowa.*;
public interface XophpCallbackOwner {
Object Callback(String method, Object... args);
}

@ -15,6 +15,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*;
import gplx.langs.regxs.*;
import gplx.core.strings.*; import gplx.core.primitives.*; import gplx.core.bits.*;
public class XophpRegex_ {
public static boolean preg_match_bool(Regx_adp pattern, int modifier, String subject) {return preg_match_bool(pattern, modifier, subject, null, 0, 0);}
public static boolean preg_match_bool(Regx_adp pattern, String subject, XophpArray matches, int flags, int offset) {return preg_match(pattern, MODIFIER_NONE, subject, matches, flags, offset) == FOUND;}
@ -70,17 +71,160 @@ public class XophpRegex_ {
}
}
}
// REF.PHP:https://www.php.net/manual/en/function.preg-match-all.php
// $flags = PREG_PATTERN_ORDER
public static int preg_match_all(Regx_adp pattern, String subject, XophpArray matches, int flags) {return preg_match_all(pattern, subject, matches, flags, 0);}
public static int preg_match_all(Regx_adp pattern, String subject, XophpArray matches, int flags, int offset) {
// decompose flags to bools
// boolean unmatched_as_null = Bitmask_.Has_int(flags, PREG_OFFSET_CAPTURE);
boolean offset_capture = Bitmask_.Has_int(flags, PREG_OFFSET_CAPTURE);
boolean pattern_order = Bitmask_.Has_int(flags, PREG_PATTERN_ORDER);
boolean set_order = Bitmask_.Has_int(flags, PREG_SET_ORDER);
if (pattern_order && set_order) { // PHP.TEST:echo(preg_match_all("|a|U", "a", $out, PREG_SET_ORDER | PREG_PATTERN_ORDER));
matches.Clear();
return 0;
}
// else if (!pattern_order && !set_order) { // occurs when passing just PREG_OFFSET_CAPTURE
// set_order = true;
// }
// ARRAY
XophpArray array_0 = null;
XophpArray array_1 = null;
boolean match_is_full = true;
if (pattern_order) {
array_0 = XophpArray.New();
array_1 = XophpArray.New();
matches.Add(array_0);
matches.Add(array_1);
}
int len = String_.Len(subject);
int count = 0;
while (offset < len) {
Regx_match match = pattern.Match(subject, offset);
if (!match.Rslt())
break;
Regx_group[] groups = match.Groups();
int groups_len = groups.length;
XophpArray array = null;
if (set_order) {
array = XophpArray.New();
matches.Add(array);
}
for (int i = 0; i < groups_len; i++) {
Regx_group group = groups[i];
if (pattern_order) {
array = match_is_full ? array_0 : array_1;
match_is_full = !match_is_full;
}
if (offset_capture) {
matches.Add(XophpArray.New(group.Val(), group.Bgn()));
}
else {
array.Add(group.Val());
}
}
offset = match.Find_end();
count++;
}
return count;
}
// REF.PHP:https://www.php.net/manual/en/function.preg-replace.php
public static final int preg_replace_limit_none = -1;
public static String preg_replace(Regx_adp pattern, String replacement, String subject) {return preg_replace(pattern, replacement, subject, -1, null);}
public static String preg_replace(Regx_adp pattern, String replacement, String subject, int limit, Int_obj_ref count_rslt) {
// if no limit specified, default to max
if (limit == preg_replace_limit_none) limit = Int_.Max_value;
// init vars for loop
int pos = 0;
int count = 0;
String_bldr sb = null;
// exec match
for (int i = 0; i < limit; i++) {
// find next
Regx_match match = pattern.Match(subject, pos);
// found nothing; stop
if (!match.Rslt()) {
if (count == 0)
return subject; // optimized case if no matches
else
break;
}
// found something
if (sb == null) {sb = String_bldr_.new_();} // lazy-make sb
// add everything up to match
sb.Add_mid(subject, pos, match.Find_bgn());
// add repl
sb.Add(replacement);
// update counters
pos = match.Find_end();
count++;
}
// add rest of String
sb.Add_mid(subject, pos, String_.Len(subject));
// update count_rslt if set
if (count_rslt != null) count_rslt.Val_(count);
// return
return sb.To_str_and_clear();
}
// REF.PHP:https://www.php.net/manual/en/pcre.constants.php
// REF.PHP:https://github.com/php/php-src/blob/master/ext/pcre/php_pcre.c
public static final int
PREG_OFFSET_CAPTURE = 256
, PREG_UNMATCHED_AS_NULL = 0
, PREG_NO_FLAG = Int_.Min_value
, PREG_ERR = -1
PREG_NO_FLAG = Int_.Min_value
, PREG_ERR = -1
, PREG_PATTERN_ORDER = 1
, PREG_SET_ORDER = 2
, PREG_OFFSET_CAPTURE = 1<<8
, PREG_UNMATCHED_AS_NULL = 1<<9
// , PREG_SPLIT_NO_EMPTY = 1<<0
// , PREG_SPLIT_DELIM_CAPTURE = 1<<1
// , PREG_SPLIT_OFFSET_CAPTURE = 1<<2
// , PREG_REPLACE_EVAL = 1<<0
//
// , PREG_GREP_INVERT = 1<<0
//
// , PREG_JIT = 1<<3
;
public static Regx_adp Pattern(String pattern) {return new Regx_adp(pattern, Regx_adp.FLAG__NONE);}
public static Regx_adp Pattern(String pattern, int modifier) {
int flags = Regx_adp.FLAG__NONE;
if (Bitmask_.Has_int(modifier, MODIFIER_i))
flags = Bitmask_.Set_or_add(flags, Regx_adp.FLAG__CASE_INSENSITIVE);
if (Bitmask_.Has_int(modifier, MODIFIER_m))
flags = Bitmask_.Set_or_add(flags, Regx_adp.FLAG__MULTILINE);
if (Bitmask_.Has_int(modifier, MODIFIER_s))
flags = Bitmask_.Set_or_add(flags, Regx_adp.FLAG__DOTALL);
if (Bitmask_.Has_int(modifier, MODIFIER_x))
flags = Bitmask_.Set_or_add(flags, Regx_adp.FLAG__COMMENTS);
if (Bitmask_.Has_int(modifier, MODIFIER_U)) {
pattern = String_.Replace(pattern, ".*", ".*?");
}
return new Regx_adp(pattern, flags);
}
public static final int NOT_FOUND = 0, FOUND = 1;
// REF.PHP:https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
// Some modifiers can be set using "(?LETTER)"; EX: "(?J)"; REF.PHP:https://www.php.net/manual/en/regexp.reference.@gplx.Internal protected-options.php
// https://stackoverflow.com/questions/5767627/how-to-add-features-missing-from-the-java-regex-implementation/5771326#5771326
public static final int
MODIFIER_NONE = 0
, MODIFIER_i = Math_.Pow_int(2, 0) // PCRE_CASELESS: If this modifier is set, letters in the pattern match both upper and lower case letters.

@ -0,0 +1,95 @@
/*
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.mediawiki; import gplx.*; import gplx.xowa.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.core.primitives.*;
import gplx.langs.regxs.*;
public class XophpRegex_match_all_tst {
private final XophpRegex_match_all_fxt fxt = new XophpRegex_match_all_fxt();
@Test public void Pattern_order() {
fxt.Test__preg_match_all
( XophpRegex_.Pattern("<[^>]+>(.*)</[^>]+>", XophpRegex_.MODIFIER_U)
, "<b>example: </b><div align=left>this is a test</div>"
, XophpRegex_.PREG_PATTERN_ORDER
, fxt.Expd()
.Add_many(XophpArray.New("<b>example: </b>", "<div align=left>this is a test</div>"))
.Add_many(XophpArray.New("example: ", "this is a test"))
);
}
// @Test public void Pattern_order_matches() {
// // PCRE does not allow duplicate named groups by default. PCRE 6.7 and later allow them if you turn on that option or use the mode modifier (?J).
// fxt.Test__preg_match_all
// ( XophpRegex_.Pattern("(?<match>foo)|(?<match>bar)", XophpRegex_.MODIFIER_U | XophpRegex_.MODIFIER_J) // (?J) changed to MODIFIER_J
// , "foo bar"
// , XophpRegex_.PREG_PATTERN_ORDER
// , fxt.Expd()
// .Add(0, "<b>example: </b>").Add(0, "<div align=left>this is a test</div>")
// .Add(1, "example: ").Add(1, "this is a test")
// );
// }
@Test public void Set_order() {
fxt.Test__preg_match_all
( XophpRegex_.Pattern("<[^>]+>(.*)</[^>]+>", XophpRegex_.MODIFIER_U)
, "<b>example: </b><div align=left>this is a test</div>"
, XophpRegex_.PREG_SET_ORDER
, fxt.Expd()
.Add_many(XophpArray.New("<b>example: </b>", "example: "))
.Add_many(XophpArray.New("<div align=left>this is a test</div>", "this is a test"))
);
}
@Test public void Offset_capture() {
fxt.Test__preg_match_all
( XophpRegex_.Pattern("(foo)(bar)(baz)", XophpRegex_.MODIFIER_U)
, "foobarbaz"
, XophpRegex_.PREG_OFFSET_CAPTURE
, fxt.Expd()
.Add_many
( XophpArray.New("foobarbaz", "0")
, XophpArray.New("foo", "0")
, XophpArray.New("bar", "3")
, XophpArray.New("baz", "6")
)
);
}
}
class XophpRegex_match_all_fxt {
public XophpRegex_match_all_expd Expd() {return new XophpRegex_match_all_expd();}
public void Test__preg_match_all(Regx_adp pattern, String subject, XophpRegex_match_all_expd rslt) {Test__preg_match_all(pattern, subject, XophpRegex_.PREG_NO_FLAG, 0, rslt);}
public void Test__preg_match_all(Regx_adp pattern, String subject, int flags, XophpRegex_match_all_expd rslt) {Test__preg_match_all(pattern, subject, flags, 0, rslt);}
public void Test__preg_match_all(Regx_adp pattern, String subject, int flags, int offset, XophpRegex_match_all_expd expd) {
XophpArray actl = XophpArray.New();
XophpRegex_.preg_match_all(pattern, subject, actl, flags, offset);
Gftest.Eq__ary__lines(expd.Ary().To_str(), actl.To_str());
}
}
class XophpRegex_match_all_expd {
public XophpArray Ary() {return ary;} private final XophpArray ary = XophpArray.New();
public XophpRegex_match_all_expd Add(int idx, Object val) {
XophpArray sub = ary.Get_at_ary(idx);
if (sub == null) {
sub = XophpArray.New();
ary.Set(idx, sub);
}
sub.Add(val);
return this;
}
public XophpRegex_match_all_expd Add_many(Object... vals) {
for (Object val : vals)
ary.Add(val);
return this;
}
}

@ -0,0 +1,49 @@
/*
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.mediawiki; import gplx.*; import gplx.xowa.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.core.primitives.*;
import gplx.langs.regxs.*;
public class XophpRegex_replace_tst {
private final XophpRegex_replace_fxt fxt = new XophpRegex_replace_fxt();
@Test public void Basic() {
// basic
fxt.Test__preg_replace("0", "1", "0ab0cd0ef", fxt.Expd("1ab1cd1ef").Count_(3));
// limit
fxt.Test__preg_replace("0", "1", "0ab0cd0ef", 2, fxt.Expd("1ab1cd0ef").Count_(2));
}
}
class XophpRegex_replace_fxt {
public XophpRegex_replace_expd Expd(String rslt) {return new XophpRegex_replace_expd(rslt);}
public void Test__preg_replace(String pattern, String replacement, String subject, XophpRegex_replace_expd rslt) {Test__preg_replace(pattern, replacement, subject, XophpRegex_.preg_replace_limit_none, rslt);}
public void Test__preg_replace(String pattern, String replacement, String subject, int limit, XophpRegex_replace_expd expd) {
Int_obj_ref actl_count = Int_obj_ref.New_zero();
String actl = XophpRegex_.preg_replace(Regx_adp_.new_(pattern), replacement, subject, limit, actl_count);
Gftest.Eq__str(expd.Rslt(), actl);
if (expd.Count() != -1)
Gftest.Eq__int(expd.Count(), actl_count.Val());
}
}
class XophpRegex_replace_expd {
public XophpRegex_replace_expd(String rslt) {
this.rslt = rslt;
}
public String Rslt() {return rslt;} private final String rslt;
public int Count() {return count;} private int count = -1;
public XophpRegex_replace_expd Count_(int v) {count = v; return this;}
}

@ -0,0 +1,19 @@
/*
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.mediawiki; import gplx.*; import gplx.xowa.*;
public class XophpRuntimeException extends XophpError { public XophpRuntimeException(String msg) {super(msg);
}
}

@ -18,7 +18,7 @@ import gplx.core.btries.*;
import gplx.core.intls.*;
import gplx.objects.strings.unicodes.*;
import gplx.core.primitives.*;
public class XophpString_ {
public class XophpString_ implements XophpCallbackOwner {
public static final String Null = null;
public static boolean is_true(String s) {return s != null;} // handles code like "if ($var)" where var is an Object;
@ -358,6 +358,11 @@ public class XophpString_ {
public static boolean is_string(Object o) {
return String_.as_(o) != null;
}
// REF.PHP: https://www.php.net/manual/en/function.strtoupper.php
public static String strtoupper(String s) {
return String_.Upper(s);
}
public static String strtolower(String s) {
return String_.Lower(s);
}
@ -462,4 +467,14 @@ public class XophpString_ {
return b >= 128 && b <= 255;
}
}
public Object Callback(String method, Object... args) {
if (String_.Eq(method, "strtoupper")) {
String val = (String)args[0];
return strtoupper(val);
}
else {
throw Err_.new_unhandled_default(method);
}
}
public static final XophpCallbackOwner Callback_owner = new XophpString_();
}

@ -1,36 +0,0 @@
/*
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.mediawiki.extensions.Wikibase.client.includes; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.extensions.*; import gplx.xowa.mediawiki.extensions.Wikibase.*; import gplx.xowa.mediawiki.extensions.Wikibase.client.*;
import gplx.xowa.mediawiki.*;
public class Wbase_client {
private Wbase_repo_linker repoLinker;
public Wbase_client(Wbase_settings settings) {
this.repoLinker = new Wbase_repo_linker
( settings.getSetting(Wbase_settings.Setting_repoUrl)
, settings.getSetting(Wbase_settings.Setting_repoArticlePath)
, settings.getSetting(Wbase_settings.Setting_repoScriptPath)
);
}
public Wbase_repo_linker RepoLinker() {return repoLinker;}
private static Wbase_client defaultInstance;
public static Wbase_client getDefaultInstance() {
if (defaultInstance == null) {
defaultInstance = new Wbase_client(Wbase_settings.New_dflt());
}
return defaultInstance;
}
}

@ -17,10 +17,10 @@ package gplx.xowa.mediawiki.extensions.Wikibase.client.includes.dataAccess.scrib
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.*; import gplx.xowa.xtns.wbases.stores.*;
import gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.Store.*; import gplx.xowa.mediawiki.extensions.Wikibase.client.config.*;
public class WikibaseLanguageIndependentLuaBindings {
private final EntityRetrievingTermLookup termLookup;
private final XomwEntityRetrievingTermLookup termLookup;
private final WikibaseClientDefault settings;
public WikibaseLanguageIndependentLuaBindings(Wbase_doc_mgr entity_mgr, byte[] wiki_abrv_wm) {
this.termLookup = new EntityRetrievingTermLookup(entity_mgr);
this.termLookup = new XomwEntityRetrievingTermLookup(entity_mgr);
this.settings = WikibaseClientDefault.New(wiki_abrv_wm);
}
public byte[] getLabelByLanguage_or_null(byte[] prefixedEntityId, byte[] languageCode) {

@ -16,9 +16,9 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
package gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.Store; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.extensions.*; import gplx.xowa.mediawiki.extensions.Wikibase.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.*;
import gplx.xowa.xtns.wbases.core.*; import gplx.xowa.xtns.wbases.claims.*; import gplx.xowa.xtns.wbases.claims.enums.*; import gplx.xowa.xtns.wbases.claims.itms.*; import gplx.xowa.xtns.wbases.stores.*;
import gplx.xowa.xtns.wbases.*;
public class EntityRetrievingTermLookup {
public class XomwEntityRetrievingTermLookup {
private final Wbase_doc_mgr entity_mgr;
public EntityRetrievingTermLookup(Wbase_doc_mgr entity_mgr) {
public XomwEntityRetrievingTermLookup(Wbase_doc_mgr entity_mgr) {
this.entity_mgr = entity_mgr;
}

@ -0,0 +1,36 @@
/*
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.mediawiki.extensions.Wikibase.lib.includes.Store; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.extensions.*; import gplx.xowa.mediawiki.extensions.Wikibase.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.*;
// REF.WBASE:2020-01-19
/**
* Interface that contains method for the PropertyOrderProvider
*
* @license GPL-2.0-or-later
* @author Lucie-Aim<EFBFBD>e Kaffee
*/
public interface XomwPropertyOrderProvider {
/**
* Get order of properties in the form [ $propertyIdSerialization => $ordinalNumber ]
*
* @return null|int[] An associative array mapping property ID strings to ordinal numbers.
* The order of properties is represented by the ordinal numbers associated with them.
* The array is not guaranteed to be sorted.
* Null if no information exists.
* @throws PropertyOrderProviderException
*/
XophpArray getPropertyOrder();
}

@ -0,0 +1,20 @@
/*
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.mediawiki.extensions.Wikibase.lib.includes.Store; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.extensions.*; import gplx.xowa.mediawiki.extensions.Wikibase.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.*;
// REF.WBASE:2020-01-19
class XomwPropertyOrderProviderException extends XophpRuntimeException { public XomwPropertyOrderProviderException(String msg) {super(msg);
}
}

@ -0,0 +1,66 @@
/*
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.mediawiki.extensions.Wikibase.lib.includes.Store; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.extensions.*; import gplx.xowa.mediawiki.extensions.Wikibase.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.*;
import gplx.xowa.mediawiki.includes.*;
import gplx.xowa.mediawiki.includes.page.*;
// REF.WBASE:2020-01-19
/**
* Provides a list of ordered Property numbers
*
* @license GPL-2.0-or-later
* @author Lucie-Aim<EFBFBD>e Kaffee
*/
class XomwWikiPagePropertyOrderProvider extends XomwWikiTextPropertyOrderProvider implements XomwPropertyOrderProvider {
/**
* @var Title
*/
private XomwTitle pageTitle;
/**
* @param Title pageTitle page name the ordered property list is on
*/
public XomwWikiPagePropertyOrderProvider(XomwTitle pageTitle) {
this.pageTitle = pageTitle;
}
/**
* Get Content of MediaWiki:Wikibase-SortedProperties
*
* @return String|null
* @throws PropertyOrderProviderException
*/
@Override protected String getPropertyOrderWikitext() {
if (!XophpObject_.is_true(this.pageTitle)) {
throw new XomwPropertyOrderProviderException("Not able to get a title");
}
// XomwWikiPage wikiPage = XomwWikiPage.factory(this.pageTitle);
//
// $pageContent = $wikiPage->getContent();
//
// if ($pageContent === null) {
// return null;
// }
//
// if (!($pageContent instanceof TextContent)) {
// throw new PropertyOrderProviderException("The page content of " + this.pageTitle->getText() + " is not TextContent");
// }
//
// return strval($pageContent->getNativeData());
return null;
}
}

@ -0,0 +1,80 @@
/*
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.mediawiki.extensions.Wikibase.lib.includes.Store; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.extensions.*; import gplx.xowa.mediawiki.extensions.Wikibase.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.*;
import gplx.langs.regxs.*;
// REF.WBASE:2020-01-19
/**
* Base cl+ass for PropertyOrderProviders, that parse the property order from a
* wikitext page.
*
* @license GPL-2.0-or-later
* @author Lucie-Aim<EFBFBD>e Kaffee
* @author Marius Hoch
*/
abstract class XomwWikiTextPropertyOrderProvider implements XomwPropertyOrderProvider {
/**
* @see parent::getPropertyOrder()
* @return null|int[] null if page doesn't exist
* @throws PropertyOrderProviderException
*/
public XophpArray getPropertyOrder() {
String pageContent = this.getPropertyOrderWikitext();
if (pageContent == null) {
return null;
}
XophpArray parsedList = this.parseList(pageContent);
return XophpArray_.array_flip(parsedList);
}
/**
* Get the wikitext of the property order list.
*
* @return String|null
* @throws PropertyOrderProviderException
*/
abstract protected String getPropertyOrderWikitext();
/**
* @param String pageContent
*
* @return String[]
*/
private XophpArray parseList(String pageContent) {
pageContent = XophpRegex_.preg_replace(parseList_replace_regx, String_.Empty, pageContent);
XophpArray orderedPropertiesMatches = XophpArray.New();
XophpRegex_.preg_match_all(
parseList_match_regx,
pageContent,
orderedPropertiesMatches,
XophpRegex_.PREG_PATTERN_ORDER
);
XophpArray orderedProperties = XophpArray_.array_map(XophpString_.Callback_owner, "strtoupper", (XophpArray)orderedPropertiesMatches.Get_at_ary(1));
return orderedProperties;
}
private static final Regx_adp
parseList_replace_regx = XophpRegex_.Pattern
( "<!--.*?-->", XophpRegex_.MODIFIER_s)
, parseList_match_regx = XophpRegex_.Pattern
//'@^\*\h*(?:\[\[(?:d:)?Property:)?(P\d+\b)@im'
( "^\\*\\h*(?:\\[\\[(?:d:)?Property:)?(P\\d+\\b)", XophpRegex_.MODIFIER_i | XophpRegex_.MODIFIER_m)
;
}

@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.Store; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.extensions.*; import gplx.xowa.mediawiki.extensions.Wikibase.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.*; import gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.xowa.mediawiki.includes.xohtml.*;
public class XomwWikiTextPropertyOrderProvider_tst {
private final XomwWikiTextPropertyOrderProvider_fxt fxt = new XomwWikiTextPropertyOrderProvider_fxt();
@Test public void Basic() {
fxt.Test__getPropertyOrder(String_.Concat_lines_nl
( "* [[Property:P1]]"
, "* [[Property:P2]]"
), XophpArray.New()
.Add("P1", "0")
.Add("P2", "1")
);
}
@Test public void Comments() {
fxt.Test__getPropertyOrder(String_.Concat_lines_nl
( "<!--* [[Property:P0]]-->"
, "* [[Property:P1]]"
, "* [[Property:P2]]"
), XophpArray.New()
.Add("P1", "0")
.Add("P2", "1")
);
}
@Test public void Invalid_properties() {
fxt.Test__getPropertyOrder(String_.Concat_lines_nl
( "* [[Property:P0a]]"
, "* [[Property:P1]]"
, "* [[Property:P2]]"
), XophpArray.New()
.Add("P1", "0")
.Add("P2", "1")
);
}
}
class XomwWikiTextPropertyOrderProvider_fxt {
public void Test__getPropertyOrder(String page, XophpArray expd) {
MockXomwWikiTextPropertyOrderProvider provider = new MockXomwWikiTextPropertyOrderProvider(page);
XophpArray actl = provider.getPropertyOrder();
Gftest.Eq__str(expd.To_str(), actl.To_str());
}
}
class MockXomwWikiTextPropertyOrderProvider extends XomwWikiTextPropertyOrderProvider { private final String text;
public MockXomwWikiTextPropertyOrderProvider(String text) {this.text = text;}
@Override protected String getPropertyOrderWikitext() {
return text;
}
}

@ -0,0 +1,190 @@
/*
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.mediawiki.includes; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*;
/**
* Hooks cl+ass.
*
* Used to supersede $wgHooks, because globals are EVIL.
*
* @since 1.18
*/
public class XomwHooks {
// /**
// * Array of events mapped to an array of callbacks to be run
// * when that event is triggered.
// */
// protected static $handlers = [];
//
// /**
// * Attach an event handler to a given hook.
// *
// * @param String $name Name of hook
// * @param callable $callback Callback function to attach
// *
// * @since 1.18
// */
// public static function register( $name, $callback ) {
// if ( !isset( self::$handlers[$name] ) ) {
// self::$handlers[$name] = [];
// }
//
// self::$handlers[$name][] = $callback;
// }
//
// /**
// * Clears hooks registered via Hooks::register(). Does not touch $wgHooks.
// * This is intended for use while testing and will fail if MW_PHPUNIT_TEST is not defined.
// *
// * @param String $name The name of the hook to clear.
// *
// * @since 1.21
// * @throws MWException If not in testing mode.
// */
// public static function clear( $name ) {
// if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
// throw new MWException( 'Cannot reset hooks in operation.' );
// }
//
// unset( self::$handlers[$name] );
// }
//
// /**
// * Returns true if a hook has a function registered to it.
// * The function may have been registered either via Hooks::register or in $wgHooks.
// *
// * @since 1.18
// *
// * @param String $name Name of hook
// * @return boolean True if the hook has a function registered to it
// */
// public static function isRegistered( $name ) {
// global $wgHooks;
// return !empty( $wgHooks[$name] ) || !empty( self::$handlers[$name] );
// }
//
// /**
// * Returns an array of all the event functions attached to a hook
// * This combines functions registered via Hooks::register and with $wgHooks.
// *
// * @since 1.18
// *
// * @param String $name Name of the hook
// * @return array
// */
// public static function getHandlers( $name ) {
// global $wgHooks;
//
// if ( !self::isRegistered( $name ) ) {
// return [];
// } elseif ( !isset( self::$handlers[$name] ) ) {
// return $wgHooks[$name];
// } elseif ( !isset( $wgHooks[$name] ) ) {
// return self::$handlers[$name];
// } else {
// return array_merge( self::$handlers[$name], $wgHooks[$name] );
// }
// }
//
// /**
// * Call hook functions defined in Hooks::register and $wgHooks.
// *
// * For a certain hook event, fetch the array of hook events and
// * process them. Determine the proper callback for each hook and
// * then call the actual hook using the appropriate arguments.
// * Finally, process the return value and return/throw accordingly.
// *
// * @param String $event Event name
// * @param array $args Array of parameters passed to hook functions
// * @param String|null $deprecatedVersion Optionally, mark hook as deprecated with version number
// * @return boolean True if no handler aborted the hook
// *
// * @throws Exception
// * @throws FatalError
// * @throws MWException
// * @since 1.22 A hook function is not required to return a value for
// * processing to continue. Not returning a value (or explicitly
// * returning null) is equivalent to returning true.
// */
// public static function run( $event, array $args = [], $deprecatedVersion = null ) {
// foreach ( self::getHandlers( $event ) as $hook ) {
// // Turn non-array values into an array. (Can't use casting because of objects.)
// if ( !is_array( $hook ) ) {
// $hook = [ $hook ];
// }
//
// if ( !array_filter( $hook ) ) {
// // Either array is empty or it's an array filled with null/false/empty.
// continue;
// } elseif ( is_array( $hook[0] ) ) {
// // First element is an array, meaning the developer intended
// // the first element to be a callback. Merge it in so that
// // processing can be uniform.
// $hook = array_merge( $hook[0], array_slice( $hook, 1 ) );
// }
//
// /**
// * $hook can be: a function, an Object, an array of $function and
// * $data, an array of just a function, an array of Object and
// * method, or an array of Object, method, and data.
// */
// if ( $hook[0] instanceof Closure ) {
// $func = "hook-$event-closure";
// $callback = array_shift( $hook );
// } elseif ( is_object( $hook[0] ) ) {
// $Object = array_shift( $hook );
// $method = array_shift( $hook );
//
// // If no method was specified, default to on$event.
// if ( $method === null ) {
// $method = "on$event";
// }
//
// $func = get_class( $Object ) . '::' . $method;
// $callback = [ $Object, $method ];
// } elseif ( is_string( $hook[0] ) ) {
// $func = $callback = array_shift( $hook );
// } else {
// throw new MWException( 'Unknown datatype in hooks for ' . $event . "\n" );
// }
//
// // Run autoloader (workaround for call_user_func_array bug)
// // and throw error if not callable.
// if ( !is_callable( $callback ) ) {
// throw new MWException( 'Invalid callback ' . $func . ' in hooks for ' . $event . "\n" );
// }
//
// // mark hook as deprecated, if deprecation version is specified
// if ( $deprecatedVersion !== null ) {
// wfDeprecated( "$event hook (used in $func)", $deprecatedVersion );
// }
//
// // Call the hook.
// $hook_args = array_merge( $hook, $args );
// $retval = call_user_func_array( $callback, $hook_args );
//
// // Process the return value.
// if ( is_string( $retval ) ) {
// // String returned means error.
// throw new FatalError( $retval );
// } elseif ( $retval === false ) {
// // False was returned. Stop processing, but no error.
// return false;
// }
// }
//
// return true;
// }
}

File diff suppressed because it is too large Load Diff

@ -15,6 +15,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.content; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
import gplx.xowa.mediawiki.includes.parsers.*;
// MW.SRC:1.33.1
/**
* A content Object represents page content, e.g. the text to show on a page.
* Content objects have no knowledge about how they relate to wiki pages.

@ -0,0 +1,49 @@
/*
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.mediawiki.includes.dao; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
/**
* Interface for database access objects.
*
* Classes using this support a set of constants in a bitfield argument to their data loading
* functions. In general, objects should assume READ_NORMAL if no flags are explicitly given,
* though certain objects may assume READ_LATEST for common use case or legacy reasons.
*
* There are four types of reads:
* - READ_NORMAL : Potentially cached read of data (e.g. from a replica DB or stale replica)
* - READ_LATEST : Up-to-date read as of transaction start (e.g. from master or a quorum read)
* - READ_LOCKING : Up-to-date read as of now, that locks (shared) the records
* - READ_EXCLUSIVE : Up-to-date read as of now, that locks (exclusive) the records
* All record locks persist for the duration of the transaction.
*
* A special constant READ_LATEST_IMMUTABLE can be used for fetching append-only data. Such
* data is either (a) on a replica DB and up-to-date or (b) not yet there, but on the master/quorum.
* Because the data is append-only, it can never be stale on a replica DB if present.
*
* Callers should use READ_NORMAL (or pass in no flags) unless the read determines a write.
* In theory, such cases may require READ_LOCKING, though to avoid contention, READ_LATEST is
* often good enough. If UPDATE race condition checks are required on a row and expensive code
* must run after the row is fetched to determine the UPDATE, it may help to do something like:
* - a) Start transaction
* - b) Read the current row with READ_LATEST
* - c) Determine the new row (expensive, so we don't want to hold locks now)
* - d) Re-read the current row with READ_LOCKING; if it changed then bail out
* - e) otherwise, do the updates
* - f) Commit transaction
*
* @since 1.20
*/
public interface XomwIDBAccessObject {
}

@ -0,0 +1,36 @@
/*
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.mediawiki.includes.dao; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
public class XomwIDBAccessObject_ {
/** Constants for Object loading bitfield flags (higher => higher QoS) */
/** @var int Read from a replica DB/non-quorum */
public static final int READ_NORMAL = 0;
/** @var int Read from the master/quorum */
public static final int READ_LATEST = 1;
/* @var int Read from the master/quorum and synchronized out other writers */
public static final int READ_LOCKING = READ_LATEST | 2; // READ_LATEST (1) and "LOCK IN SHARE MODE" (2)
/** @var int Read from the master/quorum and synchronized out other writers and locking readers */
public static final int READ_EXCLUSIVE = READ_LOCKING | 4; // READ_LOCKING (3) and "FOR UPDATE" (4)
/** @var int Read from a replica DB or without a quorum, using the master/quorum on miss */
public static final int READ_LATEST_IMMUTABLE = 8;
// Convenience constant for tracking how data was loaded (higher => higher QoS)
public static final int READ_NONE = -1; // not loaded yet (or the Object was cleared)
}

@ -0,0 +1,22 @@
/*
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.mediawiki.includes.page; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
// MW.SRC:1.33.1
/**
* Interface for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
*/
public interface XomwPage {
}

@ -0,0 +1,74 @@
/*
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.mediawiki.includes.page; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
// MW.SRC:1.33.1
/**
* Special handling for category pages
*/
public class XomwWikiCategoryPage extends XomwWikiPage { public XomwWikiCategoryPage(XomwTitle title) {super(title);
}
//
// /**
// * Don't return a 404 for categories in use.
// * In use defined as: either the actual page exists
// * or the category currently has members.
// *
// * @return boolean
// */
// public function hasViewableContent() {
// if ( parent::hasViewableContent() ) {
// return true;
// } else {
// $cat = Category::newFromTitle( $this->mTitle );
// // If any of these are not 0, then has members
// if ( $cat->getPageCount()
// || $cat->getSubcatCount()
// || $cat->getFileCount()
// ) {
// return true;
// }
// }
// return false;
// }
//
// /**
// * Checks if a category is hidden.
// *
// * @since 1.27
// *
// * @return boolean
// */
// public function isHidden() {
// $pageId = $this->getTitle()->getArticleID();
// $pageProps = PageProps::getInstance()->getProperties( $this->getTitle(), 'hiddencat' );
//
// return isset( $pageProps[$pageId] );
// }
//
// /**
// * Checks if a category is expected to be an unused category.
// *
// * @since 1.33
// *
// * @return boolean
// */
// public function isExpectedUnusedCategory() {
// $pageId = $this->getTitle()->getArticleID();
// $pageProps = PageProps::getInstance()->getProperties( $this->getTitle(), 'expectunusedcategory' );
//
// return isset( $pageProps[$pageId] );
// }
}

@ -0,0 +1,250 @@
/*
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.mediawiki.includes.page; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
// MW.SRC:1.33.1
/**
* Special handling for file pages
*
* @ingroup Media
*/
public class XomwWikiFilePage extends XomwWikiPage { // /** @var File */
// protected $mFile = false;
// /** @var LocalRepo */
// protected $mRepo = null;
// /** @var boolean */
// protected $mFileLoaded = false;
// /** @var array */
// protected $mDupes = null;
public XomwWikiFilePage(XomwTitle title) {super(title);
// $this->mDupes = null;
// $this->mRepo = null;
}
//
// /**
// * @param File $file
// */
// public function setFile( $file ) {
// $this->mFile = $file;
// $this->mFileLoaded = true;
// }
//
// /**
// * @return boolean
// */
// protected function loadFile() {
// if ( $this->mFileLoaded ) {
// return true;
// }
// $this->mFileLoaded = true;
//
// $this->mFile = wfFindFile( $this->mTitle );
// if ( !$this->mFile ) {
// $this->mFile = wfLocalFile( $this->mTitle ); // always a File
// }
// $this->mRepo = $this->mFile->getRepo();
// return true;
// }
//
// /**
// * @return mixed|null|Title
// */
// public function getRedirectTarget() {
// $this->loadFile();
// if ( $this->mFile->isLocal() ) {
// return parent::getRedirectTarget();
// }
// // Foreign image page
// $from = $this->mFile->getRedirected();
// $to = $this->mFile->getName();
// if ( $from == $to ) {
// return null;
// }
// $this->mRedirectTarget = Title::makeTitle( NS_FILE, $to );
// return $this->mRedirectTarget;
// }
//
// /**
// * @return boolean|mixed|Title
// */
// public function followRedirect() {
// $this->loadFile();
// if ( $this->mFile->isLocal() ) {
// return parent::followRedirect();
// }
// $from = $this->mFile->getRedirected();
// $to = $this->mFile->getName();
// if ( $from == $to ) {
// return false;
// }
// return Title::makeTitle( NS_FILE, $to );
// }
//
// /**
// * @return boolean
// */
// public function isRedirect() {
// $this->loadFile();
// if ( $this->mFile->isLocal() ) {
// return parent::isRedirect();
// }
//
// return (boolean)$this->mFile->getRedirected();
// }
//
// /**
// * @return boolean
// */
// public function isLocal() {
// $this->loadFile();
// return $this->mFile->isLocal();
// }
//
// /**
// * @return boolean|File
// */
// public function getFile() {
// $this->loadFile();
// return $this->mFile;
// }
//
// /**
// * @return array|null
// */
// public function getDuplicates() {
// $this->loadFile();
// if ( !is_null( $this->mDupes ) ) {
// return $this->mDupes;
// }
// $hash = $this->mFile->getSha1();
// if ( !( $hash ) ) {
// $this->mDupes = [];
// return $this->mDupes;
// }
// $dupes = RepoGroup::singleton()->findBySha1( $hash );
// // Remove duplicates with self and non matching file sizes
// $self = $this->mFile->getRepoName() . ':' . $this->mFile->getName();
// $size = $this->mFile->getSize();
//
// /**
// * @var $file File
// */
// foreach ( $dupes as $index => $file ) {
// $key = $file->getRepoName() . ':' . $file->getName();
// if ( $key == $self ) {
// unset( $dupes[$index] );
// }
// if ( $file->getSize() != $size ) {
// unset( $dupes[$index] );
// }
// }
// $this->mDupes = $dupes;
// return $this->mDupes;
// }
//
// /**
// * Override handling of action=purge
// * @return boolean
// */
// public function doPurge() {
// $this->loadFile();
//
// if ( $this->mFile->exists() ) {
// wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() . "\n" );
// DeferredUpdates::addUpdate(
// new HTMLCacheUpdate( $this->mTitle, 'imagelinks', 'file-purge' )
// );
// } else {
// wfDebug( 'ImagePage::doPurge no image for '
// . $this->mFile->getName() . "; limiting purge to cache only\n" );
// }
//
// // even if the file supposedly doesn't exist, force any cached information
// // to be updated (in case the cached information is wrong)
//
// // Purge current version and its thumbnails
// $this->mFile->purgeCache( [ 'forThumbRefresh' => true ] );
//
// // Purge the old versions and their thumbnails
// foreach ( $this->mFile->getHistory() as $oldFile ) {
// $oldFile->purgeCache( [ 'forThumbRefresh' => true ] );
// }
//
// if ( $this->mRepo ) {
// // Purge redirect cache
// $this->mRepo->invalidateImageRedirect( $this->mTitle );
// }
//
// return parent::doPurge();
// }
//
// /**
// * Get the categories this file is a member of on the wiki where it was uploaded.
// * For local files, this is the same as getCategories().
// * For foreign API files (InstantCommons), this is not supported currently.
// * Results will include hidden categories.
// *
// * @return TitleArray|Title[]
// * @since 1.23
// */
// public function getForeignCategories() {
// $this->loadFile();
// $title = $this->mTitle;
// $file = $this->mFile;
//
// if ( !$file instanceof LocalFile ) {
// wfDebug( __CLASS__ . '::' . __METHOD__ . " is not supported for this file\n" );
// return TitleArray::newFromResult( new FakeResultWrapper( [] ) );
// }
//
// /** @var LocalRepo $repo */
// $repo = $file->getRepo();
// $dbr = $repo->getReplicaDB();
//
// $res = $dbr->select(
// [ 'page', 'categorylinks' ],
// [
// 'page_title' => 'cl_to',
// 'page_namespace' => NS_CATEGORY,
// ],
// [
// 'page_namespace' => $title->getNamespace(),
// 'page_title' => $title->getDBkey(),
// ],
// __METHOD__,
// [],
// [ 'categorylinks' => [ 'JOIN', 'page_id = cl_from' ] ]
// );
//
// return TitleArray::newFromResult( $res );
// }
//
// /**
// * @since 1.28
// * @return String
// */
// public function getWikiDisplayName() {
// return $this->getFile()->getRepo()->getDisplayName();
// }
//
// /**
// * @since 1.28
// * @return String
// */
// public function getSourceURL() {
// return $this->getFile()->getDescriptionUrl();
// }
}

File diff suppressed because it is too large Load Diff

@ -18,6 +18,8 @@ import gplx.langs.jsons.*; import gplx.xowa.xtns.wbases.*; import gplx.xowa.xtns
import gplx.xowa.wikis.domains.*;
import gplx.xowa.xtns.scribunto.procs.*;
import gplx.xowa.xtns.wbases.core.*; import gplx.xowa.mediawiki.extensions.Wikibase.client.includes.*; import gplx.xowa.mediawiki.extensions.Wikibase.client.includes.dataAccess.scribunto.*;
import gplx.xowa.mediawiki.*;
import gplx.xowa.mediawiki.extensions.Wikibase.lib.includes.Store.*;
// REF.MW:https://github.com/wikimedia/mediawiki-extensions-Wikibase/blob/master/client/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibrary.php
public class Scrib_lib_wikibase implements Scrib_lib {
private final Scrib_core core;
@ -29,6 +31,57 @@ public class Scrib_lib_wikibase implements Scrib_lib {
public String Key() {return "mw.wikibase";}
public Scrib_lua_mod Mod() {return mod;} private Scrib_lua_mod mod;
public Scrib_proc_mgr Procs() {return procs;} private final Scrib_proc_mgr procs = new Scrib_proc_mgr();
// /**
// * @var WikibaseLanguageIndependentLuaBindings|null
// */
// private $languageIndependentLuaBindings = null;
//
// /**
// * @var WikibaseLanguageDependentLuaBindings|null
// */
// private $languageDependentLuaBindings = null;
//
// /**
// * @var EntityAccessor|null
// */
// private $entityAccessor = null;
//
// /**
// * @var SnakSerializationRenderer[]
// */
// private $snakSerializationRenderers = [];
//
// /**
// * @var LanguageFallbackChain|null
// */
// private $fallbackChain = null;
//
// /**
// * @var ParserOutputUsageAccumulator|null
// */
// private $usageAccumulator = null;
//
// /**
// * @var PropertyIdResolver|null
// */
// private $propertyIdResolver = null;
/**
* @var PropertyOrderProvider|null
*/
// private XomwPropertyOrderProvider propertyOrderProvider = null;
// /**
// * @var EntityIdParser|null
// */
// private $entityIdParser = null;
//
// /**
// * @var RepoLinker|null
// */
// private $repoLinker = null;
public Scrib_lib Init() {
procs.Init_by_lib(this, Proc_names);
this.wdata_mgr = core.App().Wiki_mgr().Wdata_mgr();
@ -184,7 +237,7 @@ public class Scrib_lib_wikibase implements Scrib_lib {
}
public boolean GetEntityUrl(Scrib_proc_args args, Scrib_proc_rslt rslt) {
byte[] entityId = args.Pull_bry(0);
byte[] entity_url = Wbase_client.getDefaultInstance().RepoLinker().getEntityUrl(entityId);
byte[] entity_url = WikibaseClient.getDefaultInstance().RepoLinker().getEntityUrl(entityId);
return rslt.Init_obj(entity_url);
}
public boolean GetEntityStatements(Scrib_proc_args args, Scrib_proc_rslt rslt) {
@ -277,8 +330,44 @@ public function formatValues( $snaksSerialization ) {
public boolean GetPropertyOrder(Scrib_proc_args args, Scrib_proc_rslt rslt) {
throw Err_.new_("wbase", "getPropertyOrder not implemented", "url", core.Page().Url().To_str());
}
// TEST:
// * 0 propertyIds
// * same membership, but unsorted
// * more in lhs
// * more in rhs
public boolean OrderProperties(Scrib_proc_args args, Scrib_proc_rslt rslt) {
throw Err_.new_("wbase", "orderProperties not implemented", "url", core.Page().Url().To_str());
Keyval[] propertyIds = args.Pull_kv_ary_safe(0);
// if (propertyIds.length == 0) {
// return rslt.Init_obj(propertyIds);
// }
//
// XophpArray orderedPropertiesPart = XophpArray.New();
// XophpArray unorderedProperties = XophpArray.New();
//
// // item is [{P1,1}]
// XophpArray propertyOrder = this.getPropertyOrderProvider().getPropertyOrder();
// foreach (Keyval propertyIdKv in propertyIds) {
// // item is [{0,P1}]
// String propertyId = propertyIdKv.Val_to_str_or_empty();
// if (propertyOrder.isset(propertyId)) {
// int propertyOrderSort = propertyOrder.Get_by_int(propertyId);
// orderedPropertiesPart.Set(propertyOrderSort, propertyId);
// } else {
// unorderedProperties.Add(propertyId);
// }
// }
// ksort( orderedPropertiesPart );
// orderedProperties = XophpArray_.array_merge(orderedPropertiesPart, unorderedProperties);
// Lua tables start at 1
// XophpArray orderedPropertiesResult = XophpArray_.array_combine(
// range(1, count(orderedProperties)), XophpArray_.array_values(orderedProperties)
// );
// return rslt.Init_obj(orderedPropertiesResult.To_kv_ary());
return rslt.Init_obj(propertyIds);
// throw Err_.new_("wbase", "orderProperties not implemented", "url", core.Page().Url().To_str());
}
public boolean GetLabel(Scrib_proc_args args, Scrib_proc_rslt rslt) {
Wdata_doc wdoc = Get_wdoc_or_null(args, core, "GetLabel", true);
@ -359,6 +448,17 @@ public function formatValues( $snaksSerialization ) {
if (wdoc == null && logMissing) Wdata_wiki_mgr.Log_missing_qid(core.Ctx(), type, xid_bry);
return wdoc;
}
/**
* @return PropertyOrderProvider
*/
// private XomwPropertyOrderProvider getPropertyOrderProvider() {
// if (!XophpObject_.is_true(this.propertyOrderProvider)) {
// WikibaseClient wikibaseClient = WikibaseClient.getDefaultInstance();
// this.propertyOrderProvider = wikibaseClient.getPropertyOrderProvider();
// }
// return this.propertyOrderProvider;
// }
}
/*
FOOTNOTE:GetEntityModuleName

@ -61,8 +61,7 @@ public class Scrib_lib_wikibase_entity implements Scrib_lib { // REF.MW:https://
return rslt.Init_obj(core.Wiki().Lang().Key_bry());
}
public boolean FormatStatements(Scrib_proc_args args, Scrib_proc_rslt rslt) {
throw Err_.new_unimplemented();
// return FormatPropertyValues(args, rslt); // NOTE: implementation should be like Visit_entity but return [[A]] instead of <a href='A'>
return FormatPropertyValues(args, rslt); // NOTE: implementation should be like Visit_entity but return [[A]] instead of <a href='A'>
}
public boolean FormatPropertyValues(Scrib_proc_args args, Scrib_proc_rslt rslt) {
// get qid / pid

Loading…
Cancel
Save