001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.servlet.tags.form; 018 019import javax.servlet.jsp.JspException; 020 021import org.springframework.lang.Nullable; 022import org.springframework.util.Assert; 023 024/** 025 * Abstract base class to provide common methods for implementing databinding-aware 026 * JSP tags for rendering a <i>single</i> HTML '{@code input}' element with a 027 * '{@code type}' of '{@code checkbox}' or '{@code radio}'. 028 * 029 * @author Juergen Hoeller 030 * @since 2.5.2 031 */ 032@SuppressWarnings("serial") 033public abstract class AbstractSingleCheckedElementTag extends AbstractCheckedElementTag { 034 035 /** 036 * The value of the '{@code value}' attribute. 037 */ 038 @Nullable 039 private Object value; 040 041 /** 042 * The value of the '{@code label}' attribute. 043 */ 044 @Nullable 045 private Object label; 046 047 048 /** 049 * Set the value of the '{@code value}' attribute. 050 * May be a runtime expression. 051 */ 052 public void setValue(Object value) { 053 this.value = value; 054 } 055 056 /** 057 * Get the value of the '{@code value}' attribute. 058 */ 059 @Nullable 060 protected Object getValue() { 061 return this.value; 062 } 063 064 /** 065 * Set the value of the '{@code label}' attribute. 066 * May be a runtime expression. 067 */ 068 public void setLabel(Object label) { 069 this.label = label; 070 } 071 072 /** 073 * Get the value of the '{@code label}' attribute. 074 */ 075 @Nullable 076 protected Object getLabel() { 077 return this.label; 078 } 079 080 081 /** 082 * Renders the '{@code input(radio)}' element with the configured 083 * {@link #setValue(Object) value}. Marks the element as checked if the 084 * value matches the {@link #getValue bound value}. 085 */ 086 @Override 087 protected int writeTagContent(TagWriter tagWriter) throws JspException { 088 tagWriter.startTag("input"); 089 String id = resolveId(); 090 writeOptionalAttribute(tagWriter, "id", id); 091 writeOptionalAttribute(tagWriter, "name", getName()); 092 writeOptionalAttributes(tagWriter); 093 writeTagDetails(tagWriter); 094 tagWriter.endTag(); 095 096 Object resolvedLabel = evaluate("label", getLabel()); 097 if (resolvedLabel != null) { 098 Assert.state(id != null, "Label id is required"); 099 tagWriter.startTag("label"); 100 tagWriter.writeAttribute("for", id); 101 tagWriter.appendValue(convertToDisplayString(resolvedLabel)); 102 tagWriter.endTag(); 103 } 104 105 return SKIP_BODY; 106 } 107 108 /** 109 * Write the details for the given primary tag: 110 * i.e. special attributes and the tag's value. 111 */ 112 protected abstract void writeTagDetails(TagWriter tagWriter) throws JspException; 113 114}