Renders the component.

@param component the component to paint
@param renderContext the context for rendering.
513508
@Override
	public void render(final WComponent component, final RenderContext renderContext) {
		if (renderContext instanceof WebXmlRenderContext) {
			doRender(component, (WebXmlRenderContext) renderContext);
		} else {
			throw new SystemException("Unable to render web xml output to " + renderContext);
		}
	}
1285790
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WRow row = (WRow) component;
		XmlStringBuilder xml = renderContext.getWriter();
		int cols = row.getChildCount();
		Size gap = row.getSpace();
		String gapString = gap != null ? gap.toString() : null;

		if (cols > 0) {
			xml.appendTagOpen("ui:row");
			xml.appendAttribute("id", component.getId());
			xml.appendOptionalAttribute("class", component.getHtmlClass());
			xml.appendOptionalAttribute("track", component.isTracking(), "true");
			xml.appendOptionalAttribute("gap", gapString);
			xml.appendClose();

			// Render margin
			MarginRendererUtil.renderMargin(row, renderContext);

			paintChildren(row, renderContext);

			xml.appendEndTag("ui:row");
		}
	}
50336
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WSingleSelect listBox = (WSingleSelect) component;
		XmlStringBuilder xml = renderContext.getWriter();
		String dataKey = listBox.getListCacheKey();
		boolean readOnly = listBox.isReadOnly();
		int rows = listBox.getRows();

		xml.appendTagOpen("ui:listbox");
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		xml.appendOptionalAttribute("hidden", listBox.isHidden(), "true");
		if (readOnly) {
			xml.appendAttribute("readOnly", "true");
		} else {
			xml.appendOptionalAttribute("data", dataKey != null, dataKey);
			xml.appendOptionalAttribute("disabled", listBox.isDisabled(), "true");
			xml.appendOptionalAttribute("required", listBox.isMandatory(), "true");
			xml.appendOptionalAttribute("submitOnChange", listBox.isSubmitOnChange(), "true");
			xml.appendOptionalAttribute("toolTip", component.getToolTip());
			xml.appendOptionalAttribute("accessibleText", component.getAccessibleText());
			xml.appendOptionalAttribute("rows", rows >= 2, rows);
			String autocomplete = listBox.getAutocomplete();
			xml.appendOptionalAttribute("autocomplete", !Util.empty(autocomplete), autocomplete);
		}
		xml.appendAttribute("single", "true");

		xml.appendClose();

		// Options
		List<?> options = listBox.getOptions();
		boolean renderSelectionsOnly = readOnly || dataKey != null;

		if (options != null) {
			int optionIndex = 0;
			Object selectedOption = listBox.getSelected();

			for (Object option : options) {
				if (option instanceof OptionGroup) {
					xml.appendTagOpen("ui:optgroup");
					xml.appendAttribute("label", ((OptionGroup) option).getDesc());
					xml.appendClose();

					for (Object nestedOption : ((OptionGroup) option).getOptions()) {
						renderOption(listBox, nestedOption, optionIndex++, xml, selectedOption, renderSelectionsOnly);
					}

					xml.appendEndTag("ui:optgroup");
				} else {
					renderOption(listBox, option, optionIndex++, xml, selectedOption, renderSelectionsOnly);
				}
			}
		}

		if (!readOnly) {
			DiagnosticRenderUtil.renderDiagnostics(listBox, renderContext);
		}
		xml.appendEndTag("ui:listbox");
	}
971307
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WTableRowRenderer renderer = (WTableRowRenderer) component;
		XmlStringBuilder xml = renderContext.getWriter();
		WTable table = renderer.getTable();
		TableModel dataModel = table.getTableModel();

		int[] columnOrder = table.getColumnOrder();
		final int numCols = columnOrder == null ? table.getColumnCount() : columnOrder.length;

		// Get current row details
		RowIdWrapper wrapper = renderer.getCurrentRowIdWrapper();
		List<Integer> rowIndex = wrapper.getRowIndex();

		boolean tableSelectable = table.getSelectMode() != SelectMode.NONE;
		boolean rowSelectable = tableSelectable && dataModel.isSelectable(rowIndex);
		boolean rowSelected = rowSelectable && table.getSelectedRows().contains(wrapper.getRowKey());

		boolean tableExpandable = table.getExpandMode() != WTable.ExpandMode.NONE;
		boolean rowExpandable = tableExpandable && dataModel.isExpandable(rowIndex) && wrapper.
				hasChildren();
		boolean rowExpanded = rowExpandable && table.getExpandedRows().contains(wrapper.getRowKey());

		String rowIndexAsString = TableUtil.rowIndexListToString(rowIndex);

		xml.appendTagOpen("ui:tr");
		xml.appendAttribute("rowIndex", rowIndexAsString);
		xml.appendOptionalAttribute("unselectable", !rowSelectable, "true");
		xml.appendOptionalAttribute("selected", rowSelected, "true");
		xml.appendOptionalAttribute("expandable", rowExpandable && !rowExpanded, "true");
		xml.appendClose();

		// wrote the column cell.
		boolean isRowHeader = table.isRowHeaders(); // need this before we get into the loop
		for (int i = 0; i < numCols; i++) {
			int colIndex = columnOrder == null ? i : columnOrder[i];
			WTableColumn col = table.getColumn(colIndex);
			String cellTag = "ui:td";

			if (col.isVisible()) {
				if (isRowHeader) { // The first rendered column will be the row header.
					cellTag = "ui:th";
					isRowHeader = false; // only set one col as the row header.
				}
				xml.appendTag(cellTag);
				renderer.getRenderer(colIndex).paint(renderContext);
				xml.appendEndTag(cellTag);
			}
		}

		if (rowExpandable) {
			xml.appendTagOpen("ui:subtr");
			xml.appendOptionalAttribute("open", rowExpanded, "true");
			xml.appendClose();

			if (rowExpanded || table.getExpandMode() == ExpandMode.CLIENT) {
				renderChildren(renderer, renderContext, wrapper.getChildren());
			}

			xml.appendEndTag("ui:subtr");
		}

		xml.appendEndTag("ui:tr");
	}
1186865
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WAjaxControl ajaxControl = (WAjaxControl) component;
		XmlStringBuilder xml = renderContext.getWriter();
		WComponent trigger = ajaxControl.getTrigger() == null ? ajaxControl : ajaxControl.
				getTrigger();
		int delay = ajaxControl.getDelay();

		if (ajaxControl.getTargets() == null || ajaxControl.getTargets().isEmpty()) {
			return;
		}

		// Start tag
		xml.appendTagOpen("ui:ajaxtrigger");
		xml.appendAttribute("triggerId", trigger.getId());
		xml.appendOptionalAttribute("loadOnce", ajaxControl.isLoadOnce(), "true");
		xml.appendOptionalAttribute("delay", delay > 0, delay);
		xml.appendClose();

		// Targets
		for (AjaxTarget target : ajaxControl.getTargets()) {
			xml.appendTagOpen("ui:ajaxtargetid");
			xml.appendAttribute("targetId", target.getId());
			xml.appendEnd();
		}

		// End tag
		xml.appendEndTag("ui:ajaxtrigger");
	}
150721
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WFieldSet fieldSet = (WFieldSet) component;
		XmlStringBuilder xml = renderContext.getWriter();

		xml.appendTagOpen("ui:fieldset");
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		xml.appendOptionalAttribute("hidden", fieldSet.isHidden(), "true");

		switch (fieldSet.getFrameType()) {
			case NO_BORDER:
				xml.appendOptionalAttribute("frame", "noborder");
				break;

			case NO_TEXT:
				xml.appendOptionalAttribute("frame", "notext");
				break;

			case NONE:
				xml.appendOptionalAttribute("frame", "none");
				break;

			case NORMAL:
			default:
				break;
		}

		xml.appendOptionalAttribute("required", fieldSet.isMandatory(), "true");
		xml.appendClose();

		// Render margin
		MarginRendererUtil.renderMargin(fieldSet, renderContext);

		// Label
		WDecoratedLabel label = fieldSet.getTitle();
		label.paint(renderContext);

		// Children
		xml.appendTag("ui:content");
		int size = fieldSet.getChildCount();

		for (int i = 0; i < size; i++) {
			WComponent child = fieldSet.getChildAt(i);

			// Skip label, as it has already been painted
			if (child != label) {
				child.paint(renderContext);
			}
		}

		xml.appendEndTag("ui:content");
		DiagnosticRenderUtil.renderDiagnostics(fieldSet, renderContext);
		xml.appendEndTag("ui:fieldset");
	}
624540
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WNumberField field = (WNumberField) component;
		XmlStringBuilder xml = renderContext.getWriter();
		boolean readOnly = field.isReadOnly();

		BigDecimal value = field.getValue();
		String userText = field.getText();

		xml.appendTagOpen("ui:numberfield");
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		xml.appendOptionalAttribute("hidden", component.isHidden(), "true");
		if (readOnly) {
			xml.appendAttribute("readOnly", "true");
		} else {
			WComponent submitControl = field.getDefaultSubmitButton();
			String submitControlId = submitControl == null ? null : submitControl.getId();
			BigDecimal min = field.getMinValue();
			BigDecimal max = field.getMaxValue();
			BigDecimal step = field.getStep();
			int decimals = field.getDecimalPlaces();
			xml.appendOptionalAttribute("disabled", field.isDisabled(), "true");
			xml.appendOptionalAttribute("required", field.isMandatory(), "true");
			xml.appendOptionalAttribute("toolTip", field.getToolTip());
			xml.appendOptionalAttribute("accessibleText", field.getAccessibleText());
			xml.appendOptionalAttribute("min", min != null, String.valueOf(min));
			xml.appendOptionalAttribute("max", max != null, String.valueOf(max));
			xml.appendOptionalAttribute("step", step != null, String.valueOf(step));
			xml.appendOptionalAttribute("decimals", decimals > 0, decimals);
			xml.appendOptionalAttribute("buttonId", submitControlId);

			String autocomplete = field.getAutocomplete();
			xml.appendOptionalAttribute("autocomplete", !Util.empty(autocomplete), autocomplete);
		}

		xml.appendClose();

		xml.appendEscaped(value == null ? userText : value.toString());
		if (!readOnly) {
			DiagnosticRenderUtil.renderDiagnostics(field, renderContext);
		}
		xml.appendEndTag("ui:numberfield");
	}
1305762
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WText text = (WText) component;
		XmlStringBuilder xml = renderContext.getWriter();

		String textString = text.getText();

		if (textString != null) {
			if (text.isEncodeText()) {
				xml.print(WebUtilities.encode(textString));
			} else {
				// If we are outputting unencoded content it must be XML valid.
				xml.print(HtmlToXMLUtil.unescapeToXML(textString));
			}
		}
	}
780038
@Override
	protected void afterPaint(final RenderContext renderContext) {
		super.afterPaint(renderContext);

		final int size = getChildCount();

		for (int i = 0; i < size; i++) {
			WComponent child = getChildAt(i);
			child.reset();
		}
	}
350048
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WImageEditor editorComponent = (WImageEditor) component;
		XmlStringBuilder xml = renderContext.getWriter();

		xml.appendTagOpen("wc-imageedit");
		xml.appendAttribute("id", editorComponent.getId());
		xml.appendOptionalAttribute("class", editorComponent.getHtmlClass());
		xml.appendOptionalUrlAttribute("overlay", editorComponent.getOverlayUrl());
		xml.appendOptionalAttribute("camera", editorComponent.getUseCamera());
		xml.appendOptionalAttribute("face", editorComponent.getIsFace());
		xml.appendOptionalAttribute("inline", editorComponent.getRenderInline());

		// Check for size information on the image
		Dimension size = editorComponent.getSize();
		if (size != null) {
			if (size.getHeight() >= 0) {
				xml.appendAttribute("height", size.height);
			}

			if (size.getWidth() >= 0) {
				xml.appendAttribute("width", size.width);
			}
		}

		xml.appendEnd();
	}
951825
@Override
	public void paint(final RenderContext renderContext) {
		// Set headers
		getResponse().setHeader("Cache-Control", type.getSettings());

		// Add extra no cache headers
		if (!type.isCache()) {
			getResponse().setHeader("Pragma", "no-cache");
			getResponse().setHeader("Expires", "-1");
		}

		super.paint(renderContext);
	}
1245304
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WToggleButton toggle = (WToggleButton) component;
		XmlStringBuilder xml = renderContext.getWriter();
		boolean readOnly = toggle.isReadOnly();


		xml.appendTagOpen("ui:togglebutton");
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		xml.appendOptionalAttribute("hidden", toggle.isHidden(), "true");
		xml.appendOptionalAttribute("selected", toggle.isSelected(), "true");
		if (readOnly) {
			xml.appendAttribute("readOnly", "true");
		} else {
			WComponentGroup<WCheckBox> group = toggle.getGroup();
			String groupName = group == null ? null : group.getId();
			xml.appendOptionalAttribute("groupName", groupName);
			xml.appendOptionalAttribute("disabled", toggle.isDisabled(), "true");
			xml.appendOptionalAttribute("submitOnChange", toggle.isSubmitOnChange(), "true");
			xml.appendOptionalAttribute("toolTip", toggle.getToolTip());
			xml.appendOptionalAttribute("accessibleText", toggle.getAccessibleText());
		}
		xml.appendClose();
		String text = toggle.getText();
		if (text != null) {
			xml.appendEscaped(text);
		}
		if (!readOnly) {
			DiagnosticRenderUtil.renderDiagnostics(toggle, renderContext);
		}
		xml.appendEndTag("ui:togglebutton");
	}
1279775
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WTemplate template = (WTemplate) component;

		// Setup the context
		Map<String, Object> context = new HashMap<>();
		// Make the component available under the "wc" key.
		context.put("wc", template);
		// Load the parameters
		context.putAll(template.getParameters());

		// Get template renderer for the engine
		String engine = template.getEngineName();
		if (Util.empty(engine)) {
			engine = ConfigurationProperties.getDefaultRenderingEngine();
		}
		TemplateRenderer templateRenderer = TemplateRendererFactory.newInstance(engine);

		// Render
		if (!Util.empty(template.getTemplateName())) {
			// Render the template
			templateRenderer.renderTemplate(template.getTemplateName(), context, template.getTaggedComponents(), renderContext.getWriter(),
					template.getEngineOptions());
		} else if (!Util.empty(template.getInlineTemplate())) {
			// Render inline
			templateRenderer.renderInline(template.getInlineTemplate(), context, template.getTaggedComponents(), renderContext.getWriter(),
					template.getEngineOptions());
		}
	}
780123
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WPasswordField field = (WPasswordField) component;
		XmlStringBuilder xml = renderContext.getWriter();

		boolean readOnly = field.isReadOnly();

		xml.appendTagOpen(TAG_NAME);
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		xml.appendOptionalAttribute("hidden", component.isHidden(), "true");

		if (readOnly) {
			xml.appendAttribute("readOnly", "true");
			xml.appendEnd();
			return;
		}
		int cols = field.getColumns();
		int minLength = field.getMinLength();
		int maxLength = field.getMaxLength();
		WComponent submitControl = field.getDefaultSubmitButton();
		String submitControlId = submitControl == null ? null : submitControl.getId();

		xml.appendOptionalAttribute("disabled", field.isDisabled(), "true");
		xml.appendOptionalAttribute("required", field.isMandatory(), "true");
		xml.appendOptionalAttribute("minLength", minLength > 0, minLength);
		xml.appendOptionalAttribute("maxLength", maxLength > 0, maxLength);
		xml.appendOptionalAttribute("toolTip", field.getToolTip());
		xml.appendOptionalAttribute("accessibleText", field.getAccessibleText());
		xml.appendOptionalAttribute("size", cols > 0, cols);
		xml.appendOptionalAttribute("buttonId", submitControlId);
		String placeholder = field.getPlaceholder();
		xml.appendOptionalAttribute("placeholder", !Util.empty(placeholder), placeholder);
		String autocomplete = field.getAutocomplete();
		xml.appendOptionalAttribute("autocomplete", !Util.empty(autocomplete), autocomplete);

		List<Diagnostic> diags = field.getDiagnostics(Diagnostic.ERROR);
		if (diags == null || diags.isEmpty()) {
			xml.appendEnd();
			return;
		}
		xml.appendClose();
		DiagnosticRenderUtil.renderDiagnostics(field, renderContext);
		xml.appendEndTag(TAG_NAME);
	}
1235936
@Override
	public void paint(final RenderContext renderContext) {
		getBackingComponent().paint(renderContext);

		// We don't want to remember the focus for the next render because on
		// a multi portlet page, we'd end up with multiple portlets trying to
		// set the focus.
		UIContext uic = UIContextHolder.getCurrent();

		if (uic.isFocusRequired()) {
			boolean sticky = ConfigurationProperties.getStickyFocus();

			if (!sticky) {
				uic.setFocussed(null, null);
				uic.setFocusRequired(false);
			}
		}
	}
316654
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WEditableImage editableImage = (WEditableImage) component;
		XmlStringBuilder xml = renderContext.getWriter();

		// No image set
		if (editableImage.getImage() == null && editableImage.getImageUrl() == null) {
			return;
		}

		WImageRenderer.renderTagOpen(editableImage, xml);
		WComponent uploader = editableImage.getEditUploader();
		if (uploader != null) {
			xml.appendAttribute("data-wc-editor", uploader.getId());
		}
		xml.appendEnd();
	}
346604
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WMultiTextField textField = (WMultiTextField) component;
		XmlStringBuilder xml = renderContext.getWriter();

		boolean readOnly = textField.isReadOnly();

		String[] values = textField.getTextInputs();

		xml.appendTagOpen("ui:multitextfield");
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		xml.appendOptionalAttribute("hidden", textField.isHidden(), "true");

		if (readOnly) {
			xml.appendAttribute("readOnly", "true");
		} else {
			int cols = textField.getColumns();
			int minLength = textField.getMinLength();
			int maxLength = textField.getMaxLength();
			int maxInputs = textField.getMaxInputs();
			String pattern = textField.getPattern();
			xml.appendOptionalAttribute("disabled", textField.isDisabled(), "true");
			xml.appendOptionalAttribute("required", textField.isMandatory(), "true");
			xml.appendOptionalAttribute("toolTip", textField.getToolTip());
			xml.appendOptionalAttribute("accessibleText", textField.getAccessibleText());
			xml.appendOptionalAttribute("size", cols > 0, cols);
			xml.appendOptionalAttribute("minLength", minLength > 0, minLength);
			xml.appendOptionalAttribute("maxLength", maxLength > 0, maxLength);
			xml.appendOptionalAttribute("max", maxInputs > 0, maxInputs);
			xml.appendOptionalAttribute("pattern", !Util.empty(pattern), pattern);
			// NOTE: do not use HtmlRenderUtil.getEffectivePlaceholder for placeholder - we do not want to echo "required" in every field.
			String placeholder = textField.getPlaceholder();
			xml.appendOptionalAttribute("placeholder", !Util.empty(placeholder), placeholder);
			xml.appendOptionalAttribute("title", I18nUtilities.format(null, InternalMessages.DEFAULT_MULTITEXTFIELD_TIP));
		}
		xml.appendClose();

		if (values != null) {
			for (String value : values) {
				xml.appendTag("ui:value");
				xml.appendEscaped(value);
				xml.appendEndTag("ui:value");
			}
		}

		if (!readOnly) {
			DiagnosticRenderUtil.renderDiagnostics(textField, renderContext);
		}
		xml.appendEndTag("ui:multitextfield");
	}