001// Generated by delombok at Sun Jul 30 17:21:56 UTC 2023 002package de.cuioss.test.jsf.mocks; 003 004import static de.cuioss.tools.string.MoreStrings.isEmpty; 005import java.io.IOException; 006import java.util.Map.Entry; 007import javax.faces.component.EditableValueHolder; 008import javax.faces.component.UIComponent; 009import javax.faces.component.UIInput; 010import javax.faces.component.UIOutcomeTarget; 011import javax.faces.component.UIOutput; 012import javax.faces.component.ValueHolder; 013import javax.faces.component.html.HtmlInputText; 014import javax.faces.component.html.HtmlOutcomeTargetLink; 015import javax.faces.component.html.HtmlOutputLink; 016import javax.faces.context.FacesContext; 017import javax.faces.render.Renderer; 018import de.cuioss.tools.property.PropertyHolder; 019// owolff: Not an issue because the is for tests 020/** 021 * Simple Mock renderer that is capable of rendering any element by using the 022 * simple-name of the given component. In addition it is capable of rendering 023 * the 'id'-attribute as 'id' and 'name' in case the component is of type 024 * {@link UIInput} or the attribute {@link UIComponent#getId()} is set, the 025 * 'styleClass' and 'style' attributes and reacts to the 'rendered'-attribute. 026 * It can be configured to use a certain tagname to be rendered by using 027 * {@link #CuiMockRenderer(String)}. Otherwise the simple-name of the component 028 * will be used. 029 * 030 * @author Oliver Wolff 031 */ 032@SuppressWarnings("resource") 033public class CuiMockRenderer extends Renderer { 034 private static final String OUTCOME = "outcome"; 035 private static final String TARGET = "target"; 036 private static final String VALUE = "value"; 037 private static final String STYLE_CLASS = "styleClass"; 038 private static final String STYLE_ATTRIBUTE = "style"; 039 private static final String TITLE = "title"; 040 private static final String DISABLED = "disabled"; 041 private final String tagName; 042 043 /** 044 * Default constructor resulting in the actual component to be used as tagname. 045 */ 046 public CuiMockRenderer() { 047 this(null); 048 } 049 050 @Override 051 public void encodeBegin(final FacesContext context, final UIComponent component) throws IOException { 052 if (component.isRendered()) { 053 context.getResponseWriter().startElement(getTagName(component), component); 054 writeIdAndName(context, component); 055 handleInputText(context, component); 056 writeBasicAttributes(context, component); 057 if (component instanceof EditableValueHolder) { 058 var valueHolder = (ValueHolder) component; 059 context.getResponseWriter().writeAttribute(VALUE, valueHolder.getValue(), VALUE); 060 } else if (component instanceof UIOutcomeTarget) { 061 handleOutputTarget(context, component); 062 } else if (component instanceof HtmlOutputLink) { 063 handleHtmlOutputLink(context, component); 064 } else if (component instanceof UIOutput) { 065 handleUIOutput(context, component); 066 } 067 handleOutcomeTargetLink(context, component); 068 } 069 } 070 071 private void handleOutcomeTargetLink(final FacesContext context, final UIComponent component) throws IOException { 072 if (component instanceof HtmlOutcomeTargetLink) { 073 var output = (HtmlOutcomeTargetLink) component; 074 if (null != output.getTarget()) { 075 context.getResponseWriter().writeAttribute(TARGET, output.getTarget(), TARGET); 076 } 077 } 078 } 079 080 private void handleUIOutput(final FacesContext context, final UIComponent component) throws IOException { 081 var output = (UIOutput) component; 082 if (null != output.getValue()) { 083 context.getResponseWriter().writeText(output.getValue(), VALUE); 084 } 085 } 086 087 private void handleHtmlOutputLink(final FacesContext context, final UIComponent component) throws IOException { 088 var output = (HtmlOutputLink) component; 089 if (null != output.getTarget()) { 090 context.getResponseWriter().writeAttribute(TARGET, output.getTarget(), TARGET); 091 } 092 if (null != output.getValue()) { 093 context.getResponseWriter().writeAttribute(VALUE, output.getValue(), VALUE); 094 } 095 } 096 097 private void handleOutputTarget(final FacesContext context, final UIComponent component) throws IOException { 098 var output = (UIOutcomeTarget) component; 099 if (null != output.getOutcome()) { 100 context.getResponseWriter().writeAttribute(OUTCOME, output.getOutcome(), OUTCOME); 101 } 102 if (null != output.getValue()) { 103 context.getResponseWriter().writeAttribute(VALUE, output.getValue(), VALUE); 104 } 105 } 106 107 private void writeBasicAttributes(final FacesContext context, final UIComponent component) throws IOException { 108 writeAttributeIfPresent(context, component, STYLE_CLASS, "class"); 109 writeAttributeIfPresent(context, component, STYLE_ATTRIBUTE, STYLE_ATTRIBUTE); 110 writeAttributeIfPresent(context, component, TITLE, TITLE); 111 for (Entry<String, Object> entry : component.getPassThroughAttributes(true).entrySet()) { 112 context.getResponseWriter().writeAttribute(entry.getKey(), entry.getValue(), null); 113 } 114 } 115 116 private void handleInputText(final FacesContext context, final UIComponent component) throws IOException { 117 if (component instanceof HtmlInputText) { 118 context.getResponseWriter().writeAttribute("type", "text", null); 119 if (((HtmlInputText) component).isDisabled()) { 120 context.getResponseWriter().writeAttribute(DISABLED, DISABLED, null); 121 } 122 } 123 } 124 125 private void writeIdAndName(final FacesContext context, final UIComponent component) throws IOException { 126 if (!isEmpty(component.getId()) || component instanceof UIInput) { 127 var id = component.getClientId(); 128 context.getResponseWriter().writeAttribute("id", id, null); 129 context.getResponseWriter().writeAttribute("name", id, null); 130 } 131 } 132 133 private static void writeAttributeIfPresent(final FacesContext context, final UIComponent component, final String propertyName, final String attributeName) throws IOException { 134 var holder = PropertyHolder.from(component.getClass(), propertyName); 135 if (holder.isPresent() && holder.get().getReadWrite().isReadable()) { 136 var propertyValue = holder.get().readFrom(component); 137 if (null != propertyValue) { 138 context.getResponseWriter().writeAttribute(attributeName, propertyValue, null); 139 } 140 } 141 } 142 143 @Override 144 public void encodeEnd(final FacesContext context, final UIComponent component) throws IOException { 145 if (component.isRendered()) { 146 context.getResponseWriter().endElement(getTagName(component)); 147 } 148 } 149 150 private String getTagName(final UIComponent component) { 151 if (!isEmpty(tagName)) { 152 return tagName; 153 } 154 return component.getClass().getSimpleName(); 155 } 156 157 @java.lang.SuppressWarnings("all") 158 @lombok.Generated 159 public CuiMockRenderer(final String tagName) { 160 this.tagName = tagName; 161 } 162}