package com.github.czyzby.lml.parser.impl.tag.macro; import com.github.czyzby.kiwi.util.common.Strings; import com.github.czyzby.kiwi.util.gdx.collection.GdxArrays; import com.github.czyzby.lml.parser.LmlParser; import com.github.czyzby.lml.parser.tag.LmlTag; /** Checks if passed attributes are not null or boolean false. If any of the arguments is considered null, condition * evaluates to false. Be careful when checking multiple LML arguments, for example: * * <blockquote> * * <pre> * <:notNull {arg0} {arg1}> * </pre> * * </blockquote>If one of the arguments returns a non-null value and the other is mapped to an empty string, macro will * receive only 1 attribute and will evaluate to true (effectively becoming if-any-not-null rather than * if-all-not-null). If you have arguments that might be empty (but never null!) and want if-all-not-null behavior, use * nested null check. If you really want to do this in a single tag, this might be achieved through a simple "hack": * * * <blockquote> * * <pre> * <:notNull {arg0}null {arg1}null> * </pre> * * </blockquote>If any of the arguments is an empty string in this example, the macro will still receive fixed amount of * attributes to check: 2. If the argument is empty, "null" is processed and macro evaluates to false. This, on the * other hand, fails if the argument is null, as macro will receive "nullnull" and evaluate to true. Yeah, stick to * nested tags. * * <p> * Note that his macro can be also used with named parameters:<blockquote> * * <pre> * <:notNull test="{arg0} {arg1}"> * </pre> * * </blockquote> * * @author MJ */ public class NullCheckLmlMacroTag extends AbstractConditionalLmlMacroTag { public NullCheckLmlMacroTag(final LmlParser parser, final LmlTag parentTag, final StringBuilder rawTagData) { super(parser, parentTag, rawTagData); } @Override protected boolean checkCondition() { if (GdxArrays.isEmpty(getAttributes())) { // No arguments - this might happen even if the macro was properly invoked - with an argument that returns // empty string, for example. Assuming that no params = received null. return false; } if (hasAttribute(TEST_ATTRIBUTE)) { for (final String attribute : Strings.split(getAttribute(TEST_ATTRIBUTE), ' ')) { if (!testAttribute(attribute)) { return false; } } } else { for (final String attribute : getAttributes()) { if (!testAttribute(attribute)) { return false; } } } return true; } /** @param attribute will be tested. * @return true if is null. */ private boolean testAttribute(final String attribute) { if (isAction(attribute)) { final Object result = invokeAction(attribute); if (isNullOrFalse(result)) { // Method result is empty or false. return false; } } else if (isNullOrFalse(attribute)) { // Attribute is blank, equals "null" or "false" - assuming the attribute is null. return false; } return true; } }