/**
* Copyright (C) 2012 Red Hat, Inc. and/or its affiliates.
*
* 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 org.jbpm.formModeler.core.processing.formRendering;
import org.jbpm.formModeler.core.processing.formProcessing.NamespaceManager;
import org.slf4j.Logger;
import org.jbpm.formModeler.api.model.DataHolder;
import org.jbpm.formModeler.core.config.FormManager;
import org.jbpm.formModeler.core.FieldHandlersManager;
import org.jbpm.formModeler.core.FormCoreServices;
import org.jbpm.formModeler.core.processing.FormProcessingServices;
import org.jbpm.formModeler.service.annotation.config.Config;
import org.jbpm.formModeler.service.bb.mvc.taglib.formatter.Formatter;
import org.jbpm.formModeler.service.bb.mvc.components.handling.MessagesComponentHandler;
import org.jbpm.formModeler.service.bb.mvc.taglib.formatter.FormatterException;
import org.jbpm.formModeler.api.model.Field;
import org.jbpm.formModeler.api.model.Form;
import org.jbpm.formModeler.api.model.FormDisplayInfo;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.jbpm.formModeler.core.processing.FieldHandler;
import org.jbpm.formModeler.core.processing.FormProcessor;
import org.jbpm.formModeler.core.processing.FormStatusData;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigInteger;
import java.util.*;
/**
* Renders a form.
*/
@Named("FormRenderingFormatter")
public class FormRenderingFormatter extends Formatter {
public static final String ATTR_FIELD = "_ddm_currentField";
public static final String ATTR_NAMESPACE = "_ddm_currentNamespace";
public static final String ATTR_VALUE = "_ddm_currentValue";
public static final String ATTR_INPUT_VALUE = "_ddm_currentInputValue";
public static final String ATTR_NAME = "_ddm_currentName";
public static final String ATTR_FIELD_IS_WRONG = "_ddm_currentFieldIsWrong";
public static final String ATTR_FORM_RENDER_MODE = "_ddm_current_renderMode";
public static final String ATTR_FIELD_IS_READONLY = "_ddm_fieldIsReadonly";
public static final String FIELD_CONTAINER_STYLE = "padding-top: 3px; padding-right:3px;";
private Logger log = LoggerFactory.getLogger(FormRenderingFormatter.class);
@Inject
private FormErrorMessageBuilder formErrorMessageBuilder;
@Inject
protected FieldI18nResourceObtainer fieldI18nResourceObtainer;
@Inject
protected NamespaceManager namespaceManager;
@Inject @Config("/formModeler/defaultFormErrors.jsp")
private String errorsPage;
private String[] formModes = new String[]{Form.RENDER_MODE_FORM, Form.RENDER_MODE_WYSIWYG_FORM};
private String[] displayModes = new String[]{Form.RENDER_MODE_DISPLAY, Form.RENDER_MODE_WYSIWYG_DISPLAY};
protected transient Form formToPaint;
protected transient String namespace;
protected transient String renderMode;
protected transient Boolean isReadonly = Boolean.FALSE;
protected transient FormStatusData formStatusData;
public FormManager getFormManager() {
return FormCoreServices.lookup().getFormManager();
}
public FormProcessor getFormProcessor() {
return FormProcessingServices.lookup().getFormProcessor();
}
public FieldHandlersManager getFieldHandlersManager() {
return FormProcessingServices.lookup().getFieldHandlersManager();
}
public void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws FormatterException {
Object formObject = getParameter("form");
if (formObject != null) formToPaint = (Form) formObject;
else {
log.error("Form not found");
return;
}
renderMode = (String) getParameter("renderMode"); //Default is form
String labelMode = (String) getParameter("labelMode"); //Default is before;
String reusingStatus = (String) getParameter("reuseStatus"); //Default is true;
String forceLabelModeParam = (String) getParameter("forceLabelMode"); //Default is false
String displayModeParam = (String) getParameter("displayMode");
String subForm = (String) getParameter("isSubForm");
String multiple = (String) getParameter("isMultiple");
Boolean readonly = (Boolean) getParameter("isReadonly");
if (readonly != null) isReadonly = readonly;
boolean isSubForm = subForm != null && Boolean.valueOf(subForm).booleanValue();
boolean isMultiple = multiple != null && Boolean.valueOf(multiple).booleanValue();
namespace = (String) getParameter("namespace");
if (StringUtils.isEmpty(namespace)) {
log.warn("Empty namespace is no longer permitted. Will use a default namespace value, for backwards compatibility", new Exception());
namespace = FormProcessor.DEFAULT_NAMESPACE;
} else if (!Character.isJavaIdentifierStart(namespace.charAt(0))) {
log.warn("Namespace "+namespace+" starts with an illegal character. It may cause unexpected behaviour of form under IE.");
}
Object formValues = getParameter("formValues");
if(formValues!=null){
getFormProcessor().clear(formToPaint,namespace);
getFormProcessor().read(formToPaint,namespace,(Map)formValues);
}
// Default render mode is FORM
renderMode = renderMode == null ? Form.RENDER_MODE_FORM : renderMode;
//Default label mode depends on render mode
labelMode = labelMode == null ? Form.LABEL_MODE_BEFORE : labelMode;
//if (Form.RENDER_MODE_DISPLAY.equals(renderMode)) {
// labelMode = Form.LABEL_MODE_HIDDEN;
//}
boolean reuseStatus = reusingStatus == null || Boolean.valueOf(reusingStatus).booleanValue();
boolean forceLabelMode = forceLabelModeParam != null && Boolean.valueOf(forceLabelModeParam).booleanValue();
namespace = namespace == null ? "" : namespace;
try {
if (log.isDebugEnabled()) {
log.debug("Printing form " + formToPaint.getId() + ". Mode: " + renderMode + ".");
}
String formLabelMode = formToPaint.getLabelMode();
if (formLabelMode != null && !"".equals(formLabelMode) && !Form.LABEL_MODE_UNDEFINED.equals(formLabelMode)) {
if (!forceLabelMode)
labelMode = formLabelMode;
}
if(formValues!=null){
getFormProcessor().clear(formToPaint,namespace);
formStatusData = getFormProcessor().read(formToPaint,namespace,(Map)formValues);
} else{
formStatusData = getFormProcessor().read(formToPaint, namespace);
}
String displayMode = formToPaint.getDisplayMode();
if (displayModeParam != null)
displayMode = displayModeParam;
FormDisplayInfo displayInfo = null;
if (displayMode != null) {
for (Iterator it = formToPaint.getFormDisplayInfos().iterator(); it.hasNext();) {
FormDisplayInfo info = (FormDisplayInfo) it.next();
if (info.getDisplayMode().equals(displayMode)) {
displayInfo = info;
break;
}
}
}
if (log.isDebugEnabled())
log.debug("About to display form " + formToPaint.getId() + " in namespace " + namespace);
display(formToPaint, namespace, displayMode, displayInfo, renderMode, labelMode, isSubForm, isMultiple);
} catch (Exception e) {
log.error("Error:", e);
throw new FormatterException("Error", e);
}
}
protected void setFormFieldErrors(String namespace, Form form) {
MessagesComponentHandler messagesComponentHandler = MessagesComponentHandler.lookup();
if (namespace != null && form != null) {
try {
messagesComponentHandler.getErrorsToDisplay().addAll(formErrorMessageBuilder.getWrongFormErrors(namespace, form));
} catch (Exception e) {
log.error("Error getting error messages for object " + form.getId() + ": ", e);
}
}
}
protected void display(Form form, String namespace, String displayMode, FormDisplayInfo displayInfo, String renderMode, String labelMode, boolean isSubForm, boolean isMultiple) {
if (!isSubForm || (isSubForm && isMultiple)) {
setFormFieldErrors(namespace, form);
includePage(errorsPage);
}
if (displayMode == null) {
defaultDisplay(form, namespace, renderMode, labelMode, Form.DISPLAY_MODE_DEFAULT);
}
else {
if (Form.DISPLAY_MODE_DEFAULT.equals(displayMode)) {
defaultDisplay(form, namespace, renderMode, labelMode, Form.DISPLAY_MODE_DEFAULT);
} else if (Form.DISPLAY_MODE_ALIGNED.equals(displayMode)) {
defaultDisplay(form, namespace, renderMode, labelMode, Form.DISPLAY_MODE_ALIGNED);
} else if (Form.DISPLAY_MODE_NONE.equals(displayMode)) {
defaultDisplay(form, namespace, renderMode, labelMode, Form.DISPLAY_MODE_NONE);
} else if (Form.DISPLAY_MODE_TEMPLATE.equals(displayMode)) {
templateDisplay(form, namespace, renderMode);
} else {
log.error("Unsupported display mode.");
}
}
}
public void afterRendering(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws FormatterException {
super.afterRendering(httpServletRequest, httpServletResponse);
// If form was used just to show something, clear the form status.
if (Form.RENDER_MODE_DISPLAY.equals(renderMode) || Form.RENDER_MODE_TEMPLATE_EDIT.equals(renderMode)) {
if (formToPaint != null) {
getFormProcessor().clear(formToPaint, namespace);
}
}
}
protected void templateDisplay(final Form form, final String namespace, final String renderMode) {
List renderingInstructions = FormProcessingServices.lookup().getFormTemplateHelper().getRenderingInstructions(form.getFormTemplate());
FormRenderer renderer = new FormRenderer() {
public void writeToOut(String text) {
FormRenderingFormatter.this.writeToOut(text);
}
public void renderField(String fieldName) {
Field field = form.getField(fieldName);
if (field != null) {
//setAttribute("field", field.getForm().getFormFields().iterator().next());
setAttribute("field", field);
setAttribute("hideMotionButtons", Boolean.TRUE);
FormRenderingFormatter.this.renderFragment("beforeFieldInTemplateMode");
FormRenderingFormatter.this.renderField(field, namespace, renderMode);
FormRenderingFormatter.this.renderFragment("afterFieldInTemplateMode");
} else {
setAttribute("fieldName", fieldName);
setAttribute("hideMotionButtons", Boolean.TRUE);
FormRenderingFormatter.this.renderFragment("beforeFieldInTemplateMode");
FormRenderingFormatter.this.writeToOut(Form.TEMPLATE_FIELD + "{" + fieldName + "}");
FormRenderingFormatter.this.renderFragment("afterFieldInTemplateMode");
}
}
public void renderLabel(String fieldName) {
Field field = form.getField(fieldName);
if (field != null) {
FormRenderingFormatter.this.renderFragment("beforeLabelInTemplateMode");
//FormRenderingFormatter.this.renderLabel(
// field.getForm().getFormFields().iterator().next(),
// namespace,
// renderMode
//);
FormRenderingFormatter.this.renderLabel(
field,
namespace,
renderMode
);
FormRenderingFormatter.this.renderFragment("afterLabelInTemplateMode");
} else {
FormRenderingFormatter.this.renderFragment("beforeLabelInTemplateMode");
FormRenderingFormatter.this.writeToOut(Form.TEMPLATE_LABEL + "{" + fieldName + "}");
FormRenderingFormatter.this.renderFragment("afterLabelInTemplateMode");
}
}
};
for (int i = 0; i < renderingInstructions.size(); i++) {
TemplateRenderingInstruction instruction = (TemplateRenderingInstruction) renderingInstructions.get(i);
instruction.doRender(renderer);
}
displayFooter(form);
}
protected void renderField(Field field, String namespace, String renderMode) {
beforeRenderField(field, namespace, renderMode);
boolean fieldHasErrors = formStatusData.getWrongFields().contains(field.getFieldName());
String renderPage = "";
FieldHandler fieldHandler = getFieldHandlersManager().getHandler(field.getFieldType());
if (Arrays.asList(formModes).contains(renderMode)) {
renderPage = fieldHandler.getPageToIncludeForRendering();
} else if (Arrays.asList(displayModes).contains(renderMode)) {
renderPage = fieldHandler.getPageToIncludeForDisplaying();
}
if (!"".equals(renderPage)) {
Boolean fieldIsRequired = field.getFieldRequired();
boolean fieldRequired = fieldIsRequired != null && fieldIsRequired.booleanValue();
if (fieldHasErrors) renderFragment("beforeWrongField");
if (fieldRequired) renderFragment("beforeRequiredField");
Object value = formStatusData.getCurrentValue(field.getFieldName());
boolean isStringType = String.class.getName().equals(field.getFieldType().getFieldClass());
if (value == null && isStringType) {
Map currentInputValues = formStatusData.getCurrentInputValues();
String[] values = null;
if (currentInputValues != null) {
values = ((String[]) currentInputValues.get(namespace + FormProcessor.NAMESPACE_SEPARATOR + field.getForm().getId() + FormProcessor.NAMESPACE_SEPARATOR + field.getFieldName()));
}
value = values != null && values.length > 0 ? values[0] : value;
}
setRenderingAttributes(field, namespace, value, formStatusData, fieldHasErrors);
// If disabled and/or readonly parameters were received from a subformformatter, pass them on to the included
// fields (only relevant when they're set to true)
if (isReadonly) setAttribute(ATTR_FIELD_IS_READONLY, isReadonly);
includePage(renderPage);
if (fieldRequired) renderFragment("afterRequiredField");
if (fieldHasErrors) renderFragment("afterWrongField");
} else {
if (Form.RENDER_MODE_TEMPLATE_EDIT.equals(renderMode)) {
writeToOut(Form.TEMPLATE_FIELD + "{" + field.getFieldName() + "}");
} else
log.warn("Invalid render mode " + renderMode);
}
afterRenderField(field, namespace, renderMode);
}
protected void beforeRenderField(Field field, String namespace, String renderMode) {
String uid = namespaceManager.generateSquashedInputName(namespace, field);
String fieldTypeCss = field.getFieldType().getCssStyle();
String fieldCss = field.getCssStyle();
Object overridenValue = getFormProcessor().getAttribute(field.getForm(), namespace, field.getFieldName() + ".cssStyle");
String css = fieldTypeCss;
if (!StringUtils.isEmpty(fieldCss)) {
css = fieldCss;
}
if (overridenValue != null) {
css = (String) overridenValue;
}
css = StringUtils.defaultString(css);
css = StringUtils.remove(css, ' ');
String styleToWrite = FIELD_CONTAINER_STYLE;
StringTokenizer strtk = new StringTokenizer(css, ";");
while (strtk.hasMoreTokens()) {
String tk = strtk.nextToken();
if ("display:none".equals(tk)) {
styleToWrite = tk;
break;
}
}
writeToOut("<div style=\"" + styleToWrite + "\" id=\"" + uid + "_container\">");
}
protected void afterRenderField(Field field, String namespace, String renderMode) {
writeToOut("</div>");
}
protected void renderLabel(Field field, String namespace, String renderMode) {
beforeRenderLabel(field, namespace, renderMode);
String inputId = namespaceManager.generateSquashedInputName(namespace, field);
String labelCssStyle = null;
String labelCssClass = null;
try {
labelCssStyle = field.getLabelCSSStyle();
labelCssClass = field.getLabelCSSClass();
//Check if label style was overriden by formulas.
Object style = getFormProcessor().getAttribute(field.getForm(), namespace, field.getFieldName() + ".labelCSSStyle");
if (style != null)
labelCssStyle = style.toString();
} catch (Exception e) {
log.error("Error: ", e);
}
if (Form.RENDER_MODE_TEMPLATE_EDIT.equals(renderMode)) {
writeToOut(Form.TEMPLATE_LABEL + "{" + field.getFieldName() + "}");
} else {
boolean fieldHasErrors = formStatusData.getWrongFields().contains(field.getFieldName());
String label = fieldI18nResourceObtainer.getFieldLabel(field);
Boolean fieldIsRequired = field.getFieldRequired();
boolean fieldRequired = fieldIsRequired != null && fieldIsRequired.booleanValue() && !Form.RENDER_MODE_DISPLAY.equals(fieldIsRequired);
String labelValue = StringEscapeUtils.escapeHtml4(StringUtils.defaultString(label));
writeToOut("<span id=\"" + inputId + "_label\"");
writeToOut(" class='dynInputStyle " + StringUtils.defaultString(labelCssClass) + "' ");
if (labelCssStyle != null) writeToOut(" style='" + labelCssStyle + "' ");
writeToOut(" >");
if (fieldHasErrors) writeToOut("<span class=\"skn-error\">");
if (!StringUtils.isEmpty(inputId) && !StringUtils.isEmpty(labelValue) && !Form.RENDER_MODE_DISPLAY.equals(renderMode))
writeToOut("<label for=\"" + StringEscapeUtils.escapeHtml4(inputId) + "\">");
if (fieldRequired) writeToOut("*");
writeToOut(labelValue);
if (!StringUtils.isEmpty(inputId) && !StringUtils.isEmpty(labelValue) && !Form.RENDER_MODE_DISPLAY.equals(renderMode))
writeToOut("</label>");
if (fieldRequired) renderFragment("afterRequiredLabel");
if (fieldHasErrors) writeToOut("</span>");
writeToOut("</span>");
}
afterRenderLabel(field, namespace, renderMode);
}
protected void beforeRenderLabel(Field field, String namespace, String renderMode) {
String uid = namespaceManager.generateSquashedInputName(namespace, field);
String fieldCss = field.getLabelCSSStyle();
Object overridenValue = getFormProcessor().getAttribute(field.getForm(), namespace, field.getFieldName() + ".labelCSSStyle");
String css = fieldCss;
if (overridenValue != null) {
css = (String) overridenValue;
}
css = StringUtils.defaultString(css);
css = StringUtils.remove(css, ' ');
String styleToWrite = FIELD_CONTAINER_STYLE;
StringTokenizer strtk = new StringTokenizer(css, ";");
while (strtk.hasMoreTokens()) {
String tk = strtk.nextToken();
if ("display:none".equals(tk)) {
styleToWrite = tk;
break;
}
}
writeToOut("<div style=\"" + styleToWrite + "\" id=\"" + uid + "_label_container\">");
}
protected void afterRenderLabel(Field field, String namespace, String renderMode) {
writeToOut("</div>");
}
/**
* Default display. One field after each other
*
* @param form
* @param renderMode
*/
protected void defaultDisplay(Form form, String namespace, String renderMode, String labelMode, String mode) {
Set<Field> fields = form.getFormFields();
List<Field> sortedFields = new ArrayList(fields);
Collections.sort(sortedFields, new Field.Comparator());
FormStatusData formStatusData = getFormProcessor().read(form, namespace);
setAttribute("width", deduceWidthForForm(form, renderMode, labelMode, mode));
renderFragment("outputStart");
renderFragment("formHeader");
/*Calculate colspans*/
List colspans = new ArrayList();
List fieldGroups = new ArrayList();
fieldGroups.add(new ArrayList());
for (Field field : sortedFields) {
List currentList = (List) fieldGroups.get(fieldGroups.size() - 1);
if (!Boolean.TRUE.equals(field.getGroupWithPrevious())) {
fieldGroups.add(currentList = new ArrayList());
}
currentList.add(field);
}
for (int i = 0; i < fieldGroups.size(); i++) {
List list = (List) fieldGroups.get(i);
if (!list.isEmpty())
colspans.add(new BigInteger(String.valueOf(list.size())));
}
BigInteger mcm = calculateMCM(colspans);
BigInteger max = calculateMax(colspans);
/*Render fields with colspans*/
List groupList = new ArrayList();
boolean first = true;
for (int i = 0; i < sortedFields.size(); i++) {
Field field = sortedFields.get(i);
groupList.add(field);
if (i < sortedFields.size() - 1) {
Field nextField = sortedFields.get(i + 1);
if (nextField.getGroupWithPrevious() != null && nextField.getGroupWithPrevious().booleanValue()) {
continue;
}
}
if (i > 0 && Form.DISPLAY_MODE_NONE.equals(mode)) {
renderFragment("outputEnd");
setAttribute("width", deduceWidthForForm(form, renderMode, labelMode, mode));
renderFragment("outputStart");
}
defaultDisplayGroup(form, groupList, mcm.intValue(), max.intValue(), renderMode, labelMode, formStatusData, mode, namespace, i, first);
groupList.clear();
first = false;
}
displayFooter(form);
renderFragment("outputEnd");
}
protected void displayFooter(Form form) {
String displayMode = form.getDisplayMode();
if (Form.RENDER_MODE_FORM.equals(renderMode)) {
String formRefresherFieldName = namespaceManager.generateFieldNamesPace(namespace, form, ":initialFormRefresher");
setAttribute("name", formRefresherFieldName);
setAttribute("uid", formRefresherFieldName);
if (Form.DISPLAY_MODE_TEMPLATE.equals(displayMode)) {
includePage("/formModeler/defaultFormFooter.jsp");
} else {
renderFragment("formFooter");
}
}
}
/**
* Deduce width for a form.
* @return Deduced width for a form.
*/
protected String deduceWidthForForm(Form form, String renderMode, String labelMode, String mode) {
if (Form.DISPLAY_MODE_TEMPLATE.equals(mode))
return null; //In these modes, it doesn't matter
if (Form.RENDER_MODE_DISPLAY.equals(renderMode)) { //Showing data
if (Form.DISPLAY_MODE_NONE.equals(mode)) {
return "";
} else {
return "100%";
}
} else { //Entering data
return "1%";
}
}
protected void defaultDisplayGroup(Form form, List groupMembers, int maxCols, int maxMembers, String renderMode, String labelMode, FormStatusData formStatusData, String mode, String namespace, int position, boolean first) {
int fieldColspan = maxCols / groupMembers.size();
int fieldWidth = (100 * fieldColspan) / maxCols;
if (Form.DISPLAY_MODE_ALIGNED.equals(mode)) {
fieldColspan = maxCols / maxMembers;
}
if (Form.DISPLAY_MODE_NONE.equals(mode)) {
fieldColspan = 1;
}
setAttribute("groupPosition", position);
setAttribute("field", groupMembers.get(0));
setAttribute("colspan", maxCols);
setAttribute("isFirst", first);
renderFragment("groupStart");
for (int i = 0; i < groupMembers.size(); i++) {
if (i == groupMembers.size() - 1 && Form.DISPLAY_MODE_ALIGNED.equals(mode)) {
fieldColspan = maxCols - i * maxCols / maxMembers;
fieldWidth = (100 * fieldColspan) / maxCols;
}
renderInputElement((Field) groupMembers.get(i), fieldColspan, fieldWidth, namespace, renderMode, labelMode, i);
}
setAttribute("field", groupMembers.get(groupMembers.size()-1));
setAttribute("colspan", maxCols);
renderFragment("groupEnd");
}
protected void renderInputElement(Field field, int fieldColspan, int fieldWidth, String namespace, String renderMode, String labelMode, int index) {
setAttribute("field", field);
setAttribute("colspan", fieldColspan);
setAttribute("width", fieldWidth);
setAttribute("index", index);
boolean labelInSameLine = Form.LABEL_MODE_LEFT.equals(labelMode) || Form.LABEL_MODE_RIGHT.equals(labelMode);
renderFragment("beforeInputElement");
// TODO: improve alignment for checkbox label
if((field.getFieldType().getCode().equals("CheckBox") || field.getFieldType().getCode().equals("CheckBoxPrimitiveBoolean")) && !Form.LABEL_MODE_LEFT.equals(labelMode)){
labelMode =Form.LABEL_MODE_AFTER;
labelInSameLine=true;
}
if (Form.LABEL_MODE_BEFORE.equals(labelMode) || Form.LABEL_MODE_LEFT.equals(labelMode)) {
setAttribute("colspan", fieldColspan);
setAttribute("width", fieldWidth);
setBindingAttributes(field);
renderFragment("beforeLabel");
renderLabel(field, namespace, renderMode);
renderFragment("afterLabel");
if (!labelInSameLine)
renderFragment("lineBetweenLabelAndField");
}
setAttribute("field", field);
setAttribute("colspan", fieldColspan);
setAttribute("width", fieldWidth);
renderFragment("beforeField");
renderField(field, namespace, renderMode);
setAttribute("field", field);
renderFragment("afterField");
if (Form.LABEL_MODE_AFTER.equals(labelMode) || Form.LABEL_MODE_RIGHT.equals(labelMode)) {
if (!labelInSameLine)
renderFragment("lineBetweenLabelAndField");
setAttribute("colspan", fieldColspan);
setAttribute("width", fieldWidth);
setBindingAttributes(field);
renderFragment("beforeLabel");
renderLabel(field, namespace, renderMode);
renderFragment("afterLabel");
}
setAttribute("field", field);
renderFragment("afterInputElement");
}
private void setBindingAttributes(Field field) {
DataHolder inputHolder = formToPaint.getDataHolderFromInputExpression(field.getInputBinding());
boolean hasInputBinding = !StringUtils.isEmpty(field.getInputBinding());
String color = "#444444";
setAttribute("hasInputBinding", hasInputBinding);
if (hasInputBinding) {
setAttribute("inputBindingColor", inputHolder != null ? inputHolder.getRenderColor() : color);
}
DataHolder outputHolder = formToPaint.getDataHolderFromOutputExpression(field.getOutputBinding());
boolean hasOutputBinding = !StringUtils.isEmpty(field.getOutputBinding());
if (hasOutputBinding && hasInputBinding) {
if (inputHolder != null && inputHolder.equals(outputHolder)) hasOutputBinding = false;
else if (inputHolder == null && outputHolder == null) hasOutputBinding = false;
}
setAttribute("hasOutputBinding", hasOutputBinding);
if (hasOutputBinding) {
setAttribute("outputBindingColor", outputHolder != null ? outputHolder.getRenderColor() : color);
}
}
protected BigInteger calculateMCM(List colspans) {
if (colspans == null || colspans.isEmpty()) {
return new BigInteger("1");
} else if (colspans.size() == 1) {
return (BigInteger) colspans.get(0);
} else if (colspans.size() == 2) {
BigInteger b1 = (BigInteger) colspans.get(0);
BigInteger b2 = (BigInteger) colspans.get(1);
return b1.multiply(b2).divide(b1.gcd(b2));
} else { //Size > 2
int halfLength = colspans.size() / 2;
List firstHalf = colspans.subList(0, halfLength);
List secondHalf = colspans.subList(halfLength, colspans.size());
BigInteger b1 = calculateMCM(firstHalf);
BigInteger b2 = calculateMCM(secondHalf);
return b1.multiply(b2).divide(b1.gcd(b2));
}
}
protected BigInteger calculateMax(List colspans) {
BigInteger max = new BigInteger("0");
for (int i = 0; i < colspans.size(); i++) {
BigInteger number = (BigInteger) colspans.get(i);
max = max.compareTo(number) < 0 ? number : max;
}
return max;
}
protected void setRenderingAttributes(Field field, String namespace, Object value, FormStatusData formStatusData, boolean isWrongField) {
String fieldName = namespaceManager.generateFieldNamesPace(namespace, field);
setAttribute(ATTR_FIELD, field);
setAttribute(ATTR_VALUE, value);
setAttribute(ATTR_INPUT_VALUE, formStatusData.getCurrentInputValue(fieldName));
setAttribute(ATTR_FIELD_IS_WRONG, isWrongField);
setAttribute(ATTR_NAMESPACE, namespace);
setAttribute(ATTR_NAME, fieldName);
setAttribute(ATTR_FORM_RENDER_MODE, renderMode);
}
}