S2JSFでWebParts その12
どうやら、出来た模様。
- m:srcに文字列を指定 → 今まで通り、srcで指定したファイルを読み込む
- m:srcにVB式で文字列を指定 → 解釈後の文字列を、srcとしてファイルを読み込む
- m:srcにVB式でCollection/配列を指定 → 解釈後の配列を、すべてsrcとしてファイルを読み込む
例えば、
<span m:inject="s:insert" m:src="#{hogeList}"/>こんな風に記述した時に、hogeListの中身が
{ "hoge1.html", "hoge2.html", "hoge3.html" } だと、すべて画面上に表示するというもの。
変更点は以下の通り。
まず、InsertProcessorに、m:srcを解釈して配列として返すメソッドを追加。
public Object[] getSrcs() {
String src = getSrc();
if (src == null) {
return null;
} else if (!BindingUtil.isValueReference(src)) {
return new Object[] { (String) src };
}
Object value = BindingUtil.resolveBinding(src);
if (value == null) {
return null;
} else if (value instanceof String) {
return new Object[] { (String) value };
} else if (value instanceof Collection) {
return (Object[]) new ArrayList((Collection) value).toArray();
} else if (value.getClass().isArray()) {
return (Object[]) value;
} else {
throw new IllegalStateException(JsfConstants.SRC_ATTR);
}
}
次に、InsertProcessor#processで、上で追加したメソッドを呼ぶように変更。
public void process(JsfContext jsfContext, Tag parentTag)
throws JspException {
Map insertProcessorMap = getInsertProcessorMap(jsfContext
.getPageContext());
String name = getName();
if (name != null && insertProcessorMap.containsKey(name)) {
InsertProcessor ip = (InsertProcessor) insertProcessorMap.get(name);
if (ip != this) {
ip.process(jsfContext, parentTag);
return;
}
}
// -- 変更 BEGIN
/*
String src = getSrc();
if (src != null) {
processInclude(jsfContext, parentTag, src);
} else {
processChildren(jsfContext, parentTag);
}
*/
Object[] srcs = getSrcs();
if (srcs != null) {
for (int i = 0; i < srcs.length; i++) {
processInclude(jsfContext, parentTag, (String) srcs[i]);
}
} else {
processChildren(jsfContext, parentTag);
}
// -- 変更 END
}
ViewProcessor#addIncludesも、同じように修正。
protected void addIncludes(Set includes) {
for (int i = 0; i < insertProcessors.size(); ++i) {
InsertProcessor ip = (InsertProcessor) insertProcessors.get(i);
// -- 変更 BEGIN
/*
if (src != null) {
includes.add(src);
}
*/
Object[] srcs = ip.getSrcs();
if (srcs != null) {
for (int j = 0; j < srcs.length; j++) {
includes.add((String) srcs[j]);
}
}
// -- 変更 END
}
ViewProcessor extendsViewProcessor = getExtendsViewProcessor();
if (extendsViewProcessor != null) {
includes.add(extendsPath);
extendsViewProcessor.addIncludes(includes);
}
}
ちょっと迷ったのが、
APIが変わることを気にせず、ViewProcessorからgetSrcs()を呼ぶべきか、
APIが変わらないよう、getSrc()してからViewProcessor内で式を解釈するべきか。
設計方針次第だろうけど、同じソースを重複して書きたくなかったので、前者の方法にした。
とりあえず、これで先に進めます (^^