※とりあえず"test"という属性を追加したレンダリングを行うのみ
やるべきこと
・カスタムタグクラスの作成
・カスタムUIコンポーネントクラスの作成
・カスタムレンダラーの作成
・tldファイルの作成 (タグクラスの登録とプロパティの追加)
・faces-config.xmlにUIコンポーネントとレンダラーの登録
・tldファイルの配置
・jspでのカスタムタグ使用
○カスタムタグクラスの作成
CommandLinkTagクラスを拡張してカスタムタグクラスを作成。
オーバライドするべきメソッドは以下の通り。
getRendererType() レンダラタイプを返すメソッド
getComponentType() コンポーネントタイプを返すメソッド
setProperties() JSPページに指定された属性値を、UIコンポーネントに設定するメソッド
package ui.tag;
import java.util.Map;
import javax.faces.component.UIComponent;
import com.sun.faces.taglib.html_basic.CommandLinkTag;
public class ExtLinkTag extends CommandLinkTag {
private String test;
public void setTest(String test) {
this.test = test;
}
@Override
public String getRendererType() {
return "ExtLinkRenderer";
}
@Override
public String getComponentType() {
return "ExtLink";
}
@Override
protected void setProperties(UIComponent component) {
super.setProperties(component);
Map attributeMap = component.getAttributes();
if (test != null) {
attributeMap.put("test", test);
}
}
○カスタムUIコンポーネントクラスの作成
HtmlCommandLinkクラスを拡張してカスタムUIコンポーネントクラスを作成。
オーバライドするべきメソッドは以下の通り。
getFamily() ファミリ名を返すメソッド
package ui.component;
import javax.faces.component.html.HtmlCommandLink;
public class ExtLink extends HtmlCommandLink {
@Override
public String getFamily() {
return "ExtLinkFamily";
}
} ○tldファイルの作成
タグクラスの登録とプロパティの追加を行う。
・・・ <tag> <name> extlink </name> <tag-class> ui.tag.ExtLinkTag </tag-class> <body-content> JSP </body-content> <attribute> <name> action </name> <required> false </required> <deferred-method> <method-signature> java.lang.Object action() </method-signature> </deferred-method> </attribute> <attribute> <name> actionListener </name> <required> false </required> <deferred-method> <method-signature> void actionListener(javax.faces.event.ActionEvent) </method-signature> </deferred-method> </attribute> <attribute> <name> id </name> <required> false </required> <rtexprvalue> true </rtexprvalue> </attribute> <attribute> <name> test </name> <required> false </required> <rtexprvalue> true </rtexprvalue> </attribute> ・・・
○faces-config.xmlにUIコンポーネントとレンダラーの登録
<component> <component-type>ExtLink</component-type> <component-class>ui.component.ExtLink</component-class> </component> <render-kit> <renderer> <component-family>ExtLinkFamily</component-family> <renderer-type>ExtLinkRenderer</renderer-type> <renderer-class>ui.render.ExtLinkRender</renderer-class> </renderer> </render-kit>
○カスタムレンダラーの作成
必要に応じてdecodeメソッドと各種encodeメソッドをオーバーライド。
decodeメソッドはmanagedBean適用時。
encodeメソッドはレンダリング時。
encode処理にて属性にtestを追加してみる。
decode処理はそのまま。
package ui.render;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import com.sun.faces.renderkit.AttributeManager;
import com.sun.faces.renderkit.RenderKitUtils;
import com.sun.faces.renderkit.html_basic.CommandLinkRenderer;
import com.sun.faces.renderkit.html_basic.HtmlBasicRenderer;
public class ExtLinkRender extends CommandLinkRenderer {
private static final String ATTRIBUTES[];
private static final String SCRIPT_STATE = "com.sun.faces.scriptState";
static
{
ATTRIBUTES = AttributeManager.getAttributes(com.sun.faces.renderkit.AttributeManager.Key.COMMANDLINK);
}
@Override
public void decode(FacesContext context, UIComponent component) {
super.decode(context, component);
}
@Override
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
rendererParamsNotNull(context, component);
if (!shouldEncode(component))
return;
boolean componentDisabled = Boolean.TRUE.equals(component
.getAttributes().get("disabled"));
String formClientId = getFormClientId(component, context);
if (formClientId == null && logger.isLoggable(Level.WARNING))
logger.log(Level.WARNING,
Component {0} must be enclosed inside a form, component
.getId());
if (componentDisabled || formClientId == null) {
renderAsDisabled(context, component);
} else {
if (!hasScriptBeenRendered(context)) {
RenderKitUtils.renderFormInitScript(
context.getResponseWriter(), context);
setScriptAsRendered(context);
}
renderAsActive(context, component);
}
}
protected void renderAsActive(FacesContext context, UIComponent command)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
if (writer == null)
throw new AssertionError();
String formClientId = getFormClientId(command, context);
if (formClientId == null)
return;
writer.startElement("a", command);
writeIdAttributeIfNecessary(context, writer, command);
writer.writeAttribute("href", "#", "href");
Map attributeMap = command.getAttributes();
writer.writeAttribute("test", "#", null);
RenderKitUtils.renderPassThruAttributes(writer, command, ATTRIBUTES);
RenderKitUtils.renderXHTMLStyleBooleanAttributes(writer, command);
String userOnclick = (String) command.getAttributes().get("onclick");
StringBuffer sb = new StringBuffer(128);
boolean userSpecifiedOnclick = userOnclick != null
&& !"".equals(userOnclick);
if (userSpecifiedOnclick) {
sb.append("var a=function(){");
userOnclick = userOnclick.trim();
sb.append(userOnclick);
if (userOnclick.charAt(userOnclick.length() - 1) != ';')
sb.append(';');
sb.append("};var b=function(){");
}
HtmlBasicRenderer.Param params[] = getParamList(command);
String commandClientId = command.getClientId(context);
String target = (String) command.getAttributes().get("target");
if (target != null)
target = target.trim();
else
target = "";
sb.append(getOnClickScript(formClientId, commandClientId, target,
params));
if (userSpecifiedOnclick)
sb.append("};return (a()==false) ? false : b();");
writer.writeAttribute("onclick", sb.toString(), "onclick");
writeCommonLinkAttributes(writer, command);
writeValue(command, writer);
writer.flush();
}
private static boolean hasScriptBeenRendered(FacesContext context) {
return context.getExternalContext().getRequestMap().get(
com.sun.faces.scriptState) != null;
}
private static void setScriptAsRendered(FacesContext context) {
context.getExternalContext().getRequestMap().put(
com.sun.faces.scriptState, Boolean.TRUE);
}
private static String getFormClientId(UIComponent component,
FacesContext context) {
UIForm form = getMyForm(component);
if (form != null)
return form.getClientId(context);
else
return null;
}
private static UIForm getMyForm(UIComponent component) {
UIComponent parent;
for (parent = component.getParent(); parent != null
&& !(parent instanceof UIForm); parent = parent.getParent())
;
return (UIForm) parent;
}
} ○tldファイルの配置
WEB-INF/jsf_custum.tldに配置 jsf-tlds.jarに含めてもよいと思います。
○jspでのカスタムタグ使用
taglibでtldファイル読込みとprefix定義を行う。
タグ名はtldファイルに定義したname
<%@ page contentType="text/html;charset=Shift_JIS" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="/WEB-INF/jsf_custum.tld" prefix="custom" %>
<html>
<head>
<title>HelloWorld</title>
</head>
<body>
<f:view>
<h:form>
文字を入力して下さい:<h:inputText id="string" value="#{HelloWorldBean.helloWorld}"/>
<h:commandButton value="送信"/>
<p><h:outputText id="output" value="#{HelloWorldBean.helloWorld}"/></p>
<h:commandButton id="btn1" action="ok" value="遷移" actionListener="#{HelloWorldBean.assembleMessage}" />
<br>
<custom:extlink id="link1" action="ok" actionListener="#{HelloWorldBean.assembleMessage}">カスタムリンク</custom:extlink>
</h:form>
</f:view>
</body>
</html>
0 件のコメント:
コメントを投稿