diff --git a/100_core/src/gplx/core/tests/GfoTestMethod.java b/100_core/src/gplx/core/tests/GfoTestMethod.java new file mode 100644 index 000000000..07a477322 --- /dev/null +++ b/100_core/src/gplx/core/tests/GfoTestMethod.java @@ -0,0 +1,17 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.core.tests; +public @interface GfoTestMethod {} \ No newline at end of file diff --git a/100_core/src/gplx/core/tests/Gftest.java b/100_core/src/gplx/core/tests/Gftest.java index 613ba3c90..99b45e68d 100644 --- a/100_core/src/gplx/core/tests/Gftest.java +++ b/100_core/src/gplx/core/tests/Gftest.java @@ -1,18 +1,18 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012-2017 gnosygnu@gmail.com - -XOWA is licensed under the terms of the General Public License (GPL) Version 3, -or alternatively under the terms of the Apache License Version 2.0. - -You may use XOWA according to either of these licenses as is most appropriate -for your project on a case-by-case basis. - -The terms of each license can be found in the source code repository: - -GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt -Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt -*/ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ package gplx.core.tests; import gplx.*; import gplx.core.*; import gplx.core.brys.*; public class Gftest { @@ -112,6 +112,7 @@ public class Gftest { bfr.Add(Bry__line_end); throw Err_.new_wo_type(bfr.To_str_and_clear()); } + public static void Eq__bool_n(boolean actl) {Eq__bool(Bool_.N, actl, null);} public static void Eq__bool_y(boolean actl) {Eq__bool(Bool_.Y, actl, null);} public static void Eq__bool_y(boolean actl, String msg_fmt, Object... msg_args) {Eq__bool(Bool_.Y, actl, msg_fmt, msg_args);} public static void Eq__bool(boolean expd, boolean actl) {Eq__bool(expd, actl, null);} diff --git a/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java b/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java index 26cd8bba4..eb8bc9e00 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java +++ b/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java @@ -136,6 +136,17 @@ public class XophpArray implements Bry_bfr_able { public boolean Get_by_bool(String key) {return Bool_.Cast(this.Get_by(key));} public int Get_by_int_or(String key, int or) {Object rv = this.Get_by(key); return rv == null ? or : Int_.Cast(rv);} public int Get_by_int(String key) {return Int_.Cast(this.Get_by(key));} + public XophpArray Xet_by_ary(String key) { + XophpArrayItm itm = (XophpArrayItm)hash.Get_by(key); + if (itm == null) { + XophpArray val = new XophpArray(); + this.Set(key, val); + return val; + } + else { + return (XophpArray)itm.Val(); + } + } public XophpArray Get_by_ary_or(String key, XophpArray or) {Object rv = this.Get_by(key); return rv == null ? or : (XophpArray)rv;} public XophpArray Get_by_ary(String key) {return (XophpArray)this.Get_by(key);} public String Get_by_str(char key) {return (String)this.Get_by(Char_.To_str(key));} diff --git a/400_xowa/src/gplx/xowa/mediawiki/XophpArray_.java b/400_xowa/src/gplx/xowa/mediawiki/XophpArray_.java index e18bcf47b..62aeae6c9 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/XophpArray_.java +++ b/400_xowa/src/gplx/xowa/mediawiki/XophpArray_.java @@ -211,7 +211,7 @@ public class XophpArray_ { public static Object array_pop(XophpArray array) {return array.pop();} public static boolean isset(XophpArray array, int key) {return XophpObject_.isset_obj(array.Get_at(key));} public static boolean isset(XophpArray array, String key) {return XophpObject_.isset_obj(array.Get_by(key));} - public static boolean is_array(Object array) {return array != null;} + public static boolean is_array(Object array) {return XophpType_.instance_of(array, XophpArray.class);} // REF.PHP: https://www.php.net/manual/en/function.in-array.php public static boolean in_array(Object needle, XophpArray haystack) {return in_array(needle, haystack, false);} diff --git a/400_xowa/src/gplx/xowa/mediawiki/XophpCallbackOwner.java b/400_xowa/src/gplx/xowa/mediawiki/XophpCallbackOwner.java index 23e621677..6f7aca92e 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/XophpCallbackOwner.java +++ b/400_xowa/src/gplx/xowa/mediawiki/XophpCallbackOwner.java @@ -16,4 +16,6 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt package gplx.xowa.mediawiki; public interface XophpCallbackOwner { Object Call(String method, Object... args); + + default XophpCallback NewCallback(String method) {return new XophpCallback(this, method);} } diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/XomwHooks.java b/400_xowa/src/gplx/xowa/mediawiki/includes/XomwHooks.java index 56fa41044..09dc76aa5 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/includes/XomwHooks.java +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/XomwHooks.java @@ -15,9 +15,19 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt */ package gplx.xowa.mediawiki.includes; +import gplx.String_; import gplx.core.primitives.String_obj_ref; -import gplx.xowa.mediawiki.*; +import gplx.core.tests.GfoTestMethod; +import gplx.xowa.mediawiki.XophpArray; +import gplx.xowa.mediawiki.XophpArray_; +import gplx.xowa.mediawiki.XophpCallback; +import gplx.xowa.mediawiki.XophpCallbackOwner; +import gplx.xowa.mediawiki.XophpFatalError; +import gplx.xowa.mediawiki.XophpObject_; +import gplx.xowa.mediawiki.XophpString_; +import gplx.xowa.mediawiki.XophpType_; import gplx.xowa.mediawiki.includes.exception.XomwMWException; +import gplx.xowa.mediawiki.includes.exception.XomwUnexpectedValueException; // MW.SRC:1.33.1 /** @@ -43,7 +53,7 @@ public class XomwHooks { * @since 1.18 */ public static void register(String name, XophpCallback callback) { - handlers.Get_by_ary(name).Add(callback); + handlers.Xet_by_ary(name).Add(callback); } /** @@ -153,21 +163,21 @@ public class XomwHooks { if (fname != null) fname.Val_(XophpType_.get_class(object).getName() + "::" + method); callback = new XophpCallback(object, method); } else if (XophpString_.is_string(hook.Get_at(0))) { - throw new XomwMWException("XOMW does not support string callbacks! Should not have been passed here!; event=" + event + "; fname=" + XophpArray_.array_shift(hook) + "\n"); + throw new XomwMWException("XOMW does not support string callbacks! Should not have been passed here!; event={0}; fname={1}\n", event, XophpArray_.array_shift(hook)); } else { - throw new XomwMWException("Unknown datatype in hooks for " + event + "\n"); + throw new XomwMWException("Unknown datatype in hooks for {0}\n", event); } // XOMW:skip as callback already strongly-typed above // Run autoloader (workaround for call_user_func_array bug) // and throw error if not callable. // if (!is_callable($callback)) { - // throw new MWException('Invalid callback ' . $fname . ' in hooks for ' . $event . "\n"); + // throw new XomwMWException('Invalid callback ' . $fname . ' in hooks for ' . $event . "\n"); // } // mark hook as deprecated, if deprecation version is specified if (deprecatedVersion != null) { -// wfDeprecated("$event hook (used in $fname)", deprecatedVersion); + XomwGlobalFunctions.wfDeprecated(String_.Format( "{0} hook (used in {1})", event, fname), deprecatedVersion); } // Call the hook. @@ -221,25 +231,34 @@ public class XomwHooks { return true; } -// /** -// * Call hook functions defined in Hooks::register and $wgHooks. -// * -// * @param string $event Event name -// * @param array $args Array of parameters passed to hook functions -// * @param string|null $deprecatedVersion [optional] Mark hook as deprecated with version number -// * @return bool Always true -// * @throws MWException If a callback is invalid, unknown -// * @throws UnexpectedValueException If a callback returns an abort value. -// * @since 1.30 -// */ -// public static function runWithoutAbort($event, array $args = [], $deprecatedVersion = null) { -// foreach (getHandlers($event) as hook) { -// $fname = null; -// retval = callHook($event, hook, $args, $deprecatedVersion, $fname); -// if (retval !== null && retval !== true) { -// throw new UnexpectedValueException("Invalid return from $fname for unabortable $event."); -// } -// } -// return true; -// } + /** + * Call hook functions defined in Hooks::register and $wgHooks. + * + * @param string $event Event name + * @param array $args Array of parameters passed to hook functions + * @param string|null $deprecatedVersion [optional] Mark hook as deprecated with version number + * @return bool Always true + * @throws MWException If a callback is invalid, unknown + * @throws UnexpectedValueException If a callback returns an abort value. + * @since 1.30 + */ + public static boolean runWithoutAbort(String event) {return runWithoutAbort(event, XophpArray.New(), null);} + public static boolean runWithoutAbort(String event, XophpArray args, String deprecatedVersion) { + XophpArray handlers = getHandlers(event); + int len = handlers.count(); + for (int i = 0; i < len; i++) { + Object hookObj = handlers.Get_at(i); + String_obj_ref fname = String_obj_ref.empty_(); + String retval = callHook(event, hookObj, args, deprecatedVersion, fname); + if (!XophpString_.is_null(retval) && !XophpString_.is_true(retval)) { + throw new XomwUnexpectedValueException("Invalid return from {0} for unabortable {1}.", fname, event); + } + } + return true; + } + + @GfoTestMethod + public static void clearAll() { + handlers.Clear(); + } } diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwMWException.java b/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwMWException.java index 1bbe6935e..d26f22f5c 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwMWException.java +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwMWException.java @@ -1,6 +1,6 @@ /* XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012-2017 gnosygnu@gmail.com +Copyright (C) 2012-2020 gnosygnu@gmail.com XOWA is licensed under the terms of the General Public License (GPL) Version 3, or alternatively under the terms of the Apache License Version 2.0. @@ -13,15 +13,16 @@ 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.exception; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; -import gplx.core.strings.*; -public class XomwMWException extends Err { - public XomwMWException(String msg) {super(true, "", "", msg); - } - public static Err New_by_method(Class type, String method, String msg) { - return Err_.new_wo_type(Type_.Name(type) + "." + method + ":" + msg); - } - public static Err New_by_method_obj(Object obj, String method, String msg) { - return Err_.new_wo_type(Type_.Name_by_obj(obj) + "." + method + msg); - } -} +package gplx.xowa.mediawiki.includes.exception; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; +import gplx.core.strings.*; +public class XomwMWException extends Err { + public XomwMWException(String fmt, Object... args) { + super(true, "", "", String_.Format(fmt, args)); + } + public static Err New_by_method(Class type, String method, String msg) { + return Err_.new_wo_type(Type_.Name(type) + "." + method + ":" + msg); + } + public static Err New_by_method_obj(Object obj, String method, String msg) { + return Err_.new_wo_type(Type_.Name_by_obj(obj) + "." + method + msg); + } +} diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwUnexpectedValueException.java b/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwUnexpectedValueException.java new file mode 100644 index 000000000..834e696f2 --- /dev/null +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwUnexpectedValueException.java @@ -0,0 +1,25 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.mediawiki.includes.exception; + +import gplx.Err; +import gplx.String_; + +public class XomwUnexpectedValueException extends Err { + public XomwUnexpectedValueException(String fmt, Object... args) { + super(true, "", "", String_.Format(fmt, args)); + } +}