com.formkiq.core.webflow.dialect.LayoutFieldClassAttrProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.formkiq.core.webflow.dialect.LayoutFieldClassAttrProcessor.java

Source

/*
 * Copyright (C) 2017 FormKiQ Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.formkiq.core.webflow.dialect;

import static com.formkiq.core.form.dto.FormJSONFieldType.BUTTON;
import static com.formkiq.core.form.dto.FormJSONFieldType.SIGNATURE;

import java.util.List;
import java.util.Objects;

import org.apache.commons.lang3.math.NumberUtils;
import org.thymeleaf.Arguments;
import org.thymeleaf.Configuration;
import org.thymeleaf.dom.Element;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressions;
import org.thymeleaf.standard.processor.attr.AbstractStandardSingleAttributeModifierAttrProcessor;
import org.thymeleaf.standard.processor.attr.StandardClassappendAttrProcessor;

import com.formkiq.core.form.dto.FormJSONField;
import com.formkiq.core.form.dto.FormJSONFieldType;
import com.formkiq.core.form.dto.FormJSONSection;

/**
 * Custom Layout Manager based from {@link StandardClassappendAttrProcessor}.
 *
 */
public class LayoutFieldClassAttrProcessor extends AbstractStandardSingleAttributeModifierAttrProcessor {

    /** Processor Precedence. */
    public static final int ATTR_PRECEDENCE = 1100;
    /** Processor Attribute Name. */
    // TODO rename to layoutfield
    public static final String ATTR_NAME = "layout";
    /** Processor Target Attribute Name. */
    public static final String TARGET_ATTR_NAME = "class";

    /** Default CSS Width. */
    public static final int DEFAULT_CLASS_WIDTH = 12;

    /**
     * default constructor.
     */
    public LayoutFieldClassAttrProcessor() {
        super(ATTR_NAME);
    }

    @Override
    public int getPrecedence() {
        return ATTR_PRECEDENCE;
    }

    @Override
    protected String getTargetAttributeName(final Arguments arguments, final Element element,
            final String attributeName) {
        return TARGET_ATTR_NAME;
    }

    @Override
    protected ModificationType getModificationType(final Arguments arguments, final Element element,
            final String attributeName, final String newAttributeName) {
        return ModificationType.APPEND_WITH_SPACE;
    }

    @Override
    protected boolean removeAttributeIfEmpty(final Arguments arguments, final Element element,
            final String attributeName, final String newAttributeName) {
        return true;
    }

    @Override
    protected String getTargetAttributeValue(final Arguments args, final Element element,
            final String attributeName) {

        Configuration configuration = args.getConfiguration();

        IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);

        FormJSONSection section = findVariable(configuration, parser, args, "${section}");

        String attributeValue = element.getAttributeValue(attributeName);
        FormJSONField field = findVariable(configuration, parser, args, attributeValue);

        String layoutWidth = field.getLayout().get("width");
        int width = NumberUtils.toInt(layoutWidth, DEFAULT_CLASS_WIDTH);
        String layout = "col-xs-" + width;

        if (SIGNATURE.equals(field.getType()) || BUTTON.equals(field.getType())) {
            int occurs = getOccurrences(section, field);
            layout = "col-xs-" + (DEFAULT_CLASS_WIDTH / occurs);
        }

        return layout;
    }

    /**
     * find Variable value.
     * @param <T> T
     * @param configuration {@link Configuration}
     * @param parser {@link IStandardExpressionParser}
     * @param args {@link Arguments}
     * @param attributeName {@link String}
     * @return T
     */
    @SuppressWarnings("unchecked")
    private <T> T findVariable(final Configuration configuration, final IStandardExpressionParser parser,
            final Arguments args, final String attributeName) {

        IStandardExpression expr = parser.parseExpression(configuration, args, attributeName);

        return (T) expr.execute(configuration, args);
    }

    /**
     * Get Number of Occurrences in a row.
     * @param section {@link FormJSONSection}
     * @param field {@link FormJSONField}
     * @return int
     */
    private int getOccurrences(final FormJSONSection section, final FormJSONField field) {

        int occurs = 1;
        List<FormJSONField> fields = section.getFields();
        int pos = fields.indexOf(field);

        if (pos != -1) {
            occurs += getOccurrences(fields, field.getType(), pos, true);
            occurs += getOccurrences(fields, field.getType(), pos, false);
        }

        return occurs;
    }

    /**
     * Get Number of Occurrences in a row.
     * @param fields {@link List}
     * @param fieldType {@link String}
     * @param start int
     * @param up boolean
     * @return int
     */
    private int getOccurrences(final List<FormJSONField> fields, final FormJSONFieldType fieldType, final int start,
            final boolean up) {

        int occurs = 0;
        int i = up ? start + 1 : start - 1;

        while (i >= 0 && i < fields.size()) {

            FormJSONField f = fields.get(i);
            if (fieldType != null && Objects.equals(f.getType(), fieldType)) {
                occurs++;
                i = up ? i + 1 : i - 1;
            } else {
                break;
            }
        }

        return occurs;
    }
}