継承して差分だけでSeamカスタムタグをつくる

さっそく継承でやりなおしてみました。
レンダラは元々のやつを使えば良いので自作しません。なのでファイル数も減りました。

org.richfaces.component.html.HtmlDataList2

package org.richfaces.component.html;

import java.util.Iterator;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.model.DataModel;
import org.richfaces.component.UIDataList;

/**
 * @author tagawaman
 *
 */
@SuppressWarnings("all")
public class HtmlDataList2 extends HtmlDataList {

	private String _preVar;
	public static final String COMPONENT_TYPE = "org.richfaces.DataList2";
	public static final String COMPONENT_FAMILY = "org.richfaces.DataList2";

    public HtmlDataList2() {
    	super();
    	_preVar = null;
	}

	public void setPreVar(String __preVal) {
		_preVar = __preVal;
	}

	public String getPreVar() {
		if (null != _preVar)
			return _preVar;
		ValueBinding vb = getValueBinding("preVar");
		if (null != vb)
			return (String) vb.getValue(getFacesContext());
		else
			return null;
	}

	protected void setupVariable(FacesContext faces, DataModel localModel, boolean rowSelected) {
		Map attrs = faces.getExternalContext().getRequestMap();
		if (rowSelected && isRowAvailable()) {
			setupVariable(getPreVar(), attrs, getNowVariable(getVar(), attrs));
			setupVariable(getVar(), attrs, localModel.getRowData());
			setupVariable(getStateVar(), attrs, getComponentState());
			setupVariable(getRowKeyVar(), attrs, getRowKey());
		} else {
			removeVariable(getPreVar(), attrs);
			removeVariable(getVar(), attrs);
			removeVariable(getStateVar(), attrs);
			removeVariable(getRowKeyVar(), attrs);
		}
	}

	private Object getNowVariable(String var, Map attrs) {
		return var != null ? attrs.get(var) : null;
	}

	private void setupVariable(String var, Map attrs, Object rowData) {
		if (var != null)
			attrs.put(var, rowData);
	}

	private void removeVariable(String var, Map attrs) {
		if (var != null)
			attrs.remove(var);
	}

	public Object saveState(FacesContext context) {
                Object values[] = new Object[12];
                values[0] = super.saveState(context);
                values[1] = getTitle();
                values[2] = getRowClasses();
                values[3] = getFooterClass();
                values[4] = getDir();
                values[5] = getStyleClass();
                values[6] = getStyle();
                values[7] = getLang();
                values[8] = getType();
                values[9] = getColumnClasses();
                values[10] = getHeaderClass();
                values[11] = _preVar;
                return ((Object) (values));
	}

	public void restoreState(FacesContext context, Object state) {
                Object values[] = (Object[])(Object[])state;
                super.restoreState(context, values[0]);
                setTitle((String)values[1]);
                setRowClasses((String)values[2]);
                setFooterClass((String)values[3]);
                setDir((String)values[4]);
                setStyleClass((String)values[5]);
                setStyle((String)values[6]);
                setLang((String)values[7]);
                setType((String)values[8]);
                setColumnClasses((String)values[9]);
                setHeaderClass((String)values[10]);
                _preVar = (String) values[11];
	}

	public String getFamily() {
		return "org.richfaces.DataList2";
	}
}

org.richfaces.taglib.DataList2Tag

package org.richfaces.taglib;

import javax.faces.component.UIComponent;

/**
 * @author tagawaman
 *
 */
public class DataList2Tag extends DataListTag {
	private String _preVar;

    public DataList2Tag(){
    	super();
    	_preVar = null;
    }

    public String get_preVar() {
	return _preVar;
    }

    public void set_preVar(String preVar) {
	this._preVar = preVar;
    }

    public void release(){
        super.release();
	_preVar = null;
    }

    protected void setProperties(UIComponent component){
        super.setProperties(component);
	setStringProperty(component, "preVar", _preVar);
    }

    public String getComponentType() {
	return "org.richfaces.DataList2";
    }
}

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
                              "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
	<component>
		<description />
		<component-type>org.richfaces.DataList2</component-type>
		<component-class>
			org.richfaces.component.html.HtmlDataList2
		</component-class>

		<component-extension>
			<component-family>org.richfaces.DataList2</component-family>
			<renderer-type>
				org.richfaces.DataListRenderer
			</renderer-type>
		</component-extension>
	</component>
	<render-kit>
		<render-kit-id>HTML_BASIC</render-kit-id>
		<renderer>
			<component-family>org.richfaces.DataList2</component-family>
			<renderer-type>
				org.richfaces.DataListRenderer
			</renderer-type>
			<renderer-class>
				org.richfaces.renderkit.html.DataListRenderer
			</renderer-class>
		</renderer>
	</render-kit>
</faces-config>

rich.taglib.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
  "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
  "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib xmlns="http://java.sun.com/JSF/Facelet">
	<namespace>http://richfaces.org/rich</namespace>
	<tag>
		<tag-name>dataList2</tag-name>
		<component>
			<component-type>org.richfaces.DataList2</component-type>
			<renderer-type>
				org.richfaces.DataListRenderer
			</renderer-type>
		</component>
	</tag>
</facelet-taglib>

rich.tld

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
                        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
	<tlib-version>1.2</tlib-version>
	<jsp-version>1.2</jsp-version>
	<short-name>rich</short-name>
	<uri>http://richfaces.org/rich</uri>
	<display-name>RichFaces</display-name>
	<description>RichFaces components</description>


	<tag>
		<name>dataList2</name>
		<tag-class>org.richfaces.taglib.DataList2Tag</tag-class>
		<body-content>JSP</body-content>
		<description />
		<attribute>
			<name>title</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Advisory title information about markup elements
				generated for this component
			</description>
		</attribute>
		<attribute>
			<name>rowClasses</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				A comma-delimited list of CSS style classes that is
				applied to popup table rows. A space separated list of
				classes may also be specified for any individual row.
				The styles are applied, in turn, to each row in the
				table. For example, if the list has two elements, the
				first style class in the list is applied to the first
				row, the second to the second row, the first to the
				third row, the second to the fourth row, etc. In other
				words, we keep iterating through the list until we reach
				the end, and then we start at the beginning again
			</description>
		</attribute>
		<attribute>
			<name>stateVar</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				The attribute provides access to a component state on
				the client side
			</description>
		</attribute>
		<attribute>
			<name>componentState</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				It defines EL-binding for a component state for saving
				or redefinition
			</description>
		</attribute>
		<attribute>
			<name>rowKeyVar</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				The attribute provides access to a row key in a Request
				scope
			</description>
		</attribute>
		<attribute>
			<name>rendered</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				If "false", this component is not rendered
			</description>
		</attribute>
		<attribute>
			<name>footerClass</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Space-separated list of CSS style class(es) that are be
				applied to any footer generated for this table
			</description>
		</attribute>
		<attribute>
			<name>dir</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Direction indication for text that does not inherit
				directionality. Valid values are "LTR" (left-to-right)
				and "RTL" (right-to-left)
			</description>
		</attribute>
		<attribute>
			<name>id</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Every component may have a unique id that is
				automatically created if omitted
			</description>
		</attribute>
		<attribute>
			<name>styleClass</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Corresponds to the HTML class attribute
			</description>
		</attribute>
		<attribute>
			<name>ajaxKeys</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				This attribute defines rows that are updated after an
				AJAX request
			</description>
		</attribute>
		<attribute>
			<name>rowKey</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				RowKey is a representation of an identifier for a
				specific data row
			</description>
		</attribute>
		<attribute>
			<name>style</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				CSS style(s) is/are to be applied when this component is
				rendered
			</description>
		</attribute>
		<attribute>
			<name>var</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				A request-scope attribute via which the data object for
				the current row will be used when iterating
			</description>
		</attribute>
		<attribute>
			<name>preVar</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				A request-scope attribute via which the data object for
				the pre-row will be used when iterating
			</description>
		</attribute>
		<attribute>
			<name>value</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				The current value for this component
			</description>
		</attribute>
		<attribute>
			<name>rows</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				A number of rows to display, or zero for all remaining
				rows in the table
			</description>
		</attribute>
		<attribute>
			<name>lang</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Code describing the language used in the generated
				markup for this component
			</description>
		</attribute>
		<attribute>
			<name>type</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Corresponds to the HTML DL type attribute
			</description>
		</attribute>
		<attribute>
			<name>columnClasses</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Comma-delimited list of CSS style classes that are be
				applied to the columns of this table. A space separated
				list of classes may also be specified for any individual
				column. If the number of elements in this list is less
				than the number of columns specified in the "columns"
				attribute, no "class" attribute is output for each
				column greater than the number of elements in the list.
				If the number of elements in the list is greater than
				the number of columns specified in the "columns"
				attribute, the elements at the position in the list
				after the value of the "columns" attribute are ignored
			</description>
		</attribute>
		<attribute>
			<name>first</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				A zero-relative row number of the first row to display
			</description>
		</attribute>
		<attribute>
			<name>headerClass</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				Space-separated list of CSS style class(es) that are be
				applied to any header generated for this table
			</description>
		</attribute>
		<attribute>
			<name>binding</name>
			<rtexprvalue>false</rtexprvalue>
			<description>
				The attribute takes a value-binding expression for a
				component property of a backing bean
			</description>
		</attribute>
	</tag>
</taglib>

以上。どっちも同じ機能だけど、やっぱり楽な方がいいよね。
継承したやつ使おっと。