package com.github.czyzby.lml.vis.parser.impl.tag.validator; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.utils.ObjectSet; import com.github.czyzby.kiwi.util.common.Strings; import com.github.czyzby.kiwi.util.gdx.collection.GdxSets; import com.github.czyzby.lml.parser.LmlParser; import com.github.czyzby.lml.parser.impl.tag.AbstractLmlTag; import com.github.czyzby.lml.parser.tag.LmlTag; import com.github.czyzby.lml.util.LmlUtilities; import com.github.czyzby.lml.vis.parser.impl.tag.FormValidatorLmlTag; import com.kotcrab.vis.ui.util.InputValidator; import com.kotcrab.vis.ui.util.form.FormInputValidator; import com.kotcrab.vis.ui.util.form.ValidatorWrapper; import com.kotcrab.vis.ui.widget.VisValidatableTextField; /** Abstract base for {@link InputValidator} tags. * * @author MJ */ public abstract class AbstractValidatorLmlTag extends AbstractLmlTag { public AbstractValidatorLmlTag(final LmlParser parser, final LmlTag parentTag, final StringBuilder rawTagData) { super(parser, parentTag, rawTagData); } @Override public void handleDataBetweenTags(final CharSequence rawData) { if (Strings.isNotBlank(rawData)) { getParser().throwErrorIfStrict("Validators cannot parse plain text between tags."); } } @Override public Actor getActor() { return null; } /** @return managed {@link InputValidator}. */ @Override public Object getManagedObject() { return getInputValidator(); } @Override public void closeTag() { if (getParent() == null) { getParser().throwError("Validators need to be attached to a tag. No parent found for tag: " + getTagName()); } } @Override public void handleChild(final LmlTag childTag) { getParser().throwErrorIfStrict("Validators cannot have children."); } /** @return {@link InputValidator} supplied by this tag. Invoked once, when validator is attached to the actor. */ public abstract InputValidator getInputValidator(); @Override protected boolean supportsNamedAttributes() { return true; } @Override public boolean isAttachable() { return true; } @Override public void attachTo(final LmlTag tag) { final InputValidator validator = initiateValidator(); doBeforeAttach(validator); if (tag.getActor() instanceof VisValidatableTextField) { ((VisValidatableTextField) tag.getActor()).addValidator(validator); } else { getParser().throwErrorIfStrict("Validators can be attached only to VisValidatableTextField actors."); } } /** Invoked before the validator is attached. * * @param validator has been initiated. */ protected void doBeforeAttach(final InputValidator validator) { } private InputValidator initiateValidator() { final InputValidator validator = getInputValidator(); if (isInForm() && !(validator instanceof FormInputValidator)) { return wrapValidator(validator); } processAttributes(validator); return validator; } private InputValidator wrapValidator(final InputValidator validator) { final ObjectSet<String> processedAttributes = GdxSets.newSet(); processAttributes(validator, processedAttributes, false); // Processing form validator-specific attributes: final FormInputValidator formValidator = new ValidatorWrapper(Strings.EMPTY_STRING, validator); processAttributes(formValidator, processedAttributes, true); return formValidator; } /** @return true if the validator is attached to a widget in a form. */ protected boolean isInForm() { LmlTag parent = getParent(); while (parent != null) { if (parent instanceof FormValidatorLmlTag) { return true; } parent = parent.getParent(); } return false; } // Utility named attribute processing methods: private void processAttributes(final InputValidator validator) { processAttributes(validator, null, true); } private void processAttributes(final InputValidator validator, final ObjectSet<String> processedAttributes, final boolean throwExceptionIfAttributeUnknown) { LmlUtilities.processAttributes(validator, this, getParser(), processedAttributes, throwExceptionIfAttributeUnknown); } }