Teedaネスト対応
これで実験してから一年半ぐらい経過していますが、組んでみました。
data3Dto = new Data3Dto(); data3Dto.data5 = "DataText5"; data3Dto.data6 = "DataText6"; data3Dto.data2Dto = new Data2Dto(); data3Dto.data2Dto.data3 = "DataText3"; data3Dto.data2Dto.data4 = "DataText4"; data3Dto.data2Dto.dataDto = new DataDto(); data3Dto.data2Dto.dataDto.data1 = "DataText1"; data3Dto.data2Dto.dataDto.data2 = "DataText2";
こんな感じのデータが
<span id="data3Dto_data5">data3Dto_data5</span><br /> <span id="data3Dto_data6">data3Dto_data6</span><br /> <span id="data3Dto_data2Dto_data3">data3Dto_data2Dto_data3</span><br /> <span id="data3Dto_data2Dto_data4">data3Dto_data2Dto_data4</span><br /> <span id="data3Dto_data2Dto_dataDto_data1">data3Dto_data2Dto_dataDto_data1</span><br /> <span id="data3Dto_data2Dto_dataDto_data2">data3Dto_data2Dto_dataDto_data2</span><br /> <span id="data3Dto_data2Dto_dataDto_data3">data3Dto_data2Dto_dataDto_data3</span><br />
こんな感じで利用できます。
最後のdata3Dto_data2Dto_dataDto_data3はプロパティーがないので、データが入らない状態ででます。標準だと例外エラーになるのでここのチェックが一番面倒だと思います。
以下パッチですが、
http://akira.info/labs/NestTeeda/teeda.patch
http://akira.info/labs/NestTeeda/teedaNest20110224.lzh
ここにパッチと、サンプルで動いているプロジェクト起きました。
Eclipseのパッチはなんかおかしい。。。ひとつだけ適応されないところがでてきています(涙)
もう少しテストを書く必要があるけれど、普通にデータ表示するだけだったらこれでいいのかな?
性能実験やっていないので、もう少し速度的な最適化はできるきがします。
Index: teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/TagProcessorAssembleImplTest.java =================================================================== --- teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/TagProcessorAssembleImplTest.java (revision 4307) +++ teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/TagProcessorAssembleImplTest.java (working copy) @@ -450,6 +450,10 @@ return false; } + public boolean hasNestProperty(String name) { + return false; + } + public boolean isModified() { return false; } Index: teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/page/AaaDto.java =================================================================== --- teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/page/AaaDto.java (revision 4307) +++ teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/page/AaaDto.java (working copy) @@ -19,10 +19,11 @@ /** * @author higa - * + * */ public class AaaDto implements Serializable { public static final String COMPONENT = "instance=session"; + public String aaaBbb; } Index: teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/PageDescImplTest.java =================================================================== --- teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/PageDescImplTest.java (revision 4307) +++ teeda-extension/src/test/java/org/seasar/teeda/extension/html/impl/PageDescImplTest.java (working copy) @@ -43,6 +43,15 @@ assertFalse(pd.hasProperty(null)); } + public void testHasNestProperty() throws Exception { + PageDesc pd = createPageDesc(FooPage.class, "fooPage"); + assertFalse(pd.hasNestProperty("aaa")); + assertFalse(pd.hasNestProperty("aaaDto")); + assertTrue(pd.hasNestProperty("aaaDto_aaaBbb")); + assertFalse(pd.hasNestProperty(null)); + } + + public void testHasItemsProperty() throws Exception { PageDesc pd = createPageDesc(FooPage.class, "fooPage"); assertTrue(pd.hasItemsProperty("cccItems")); Index: teeda-extension/src/main/java/org/seasar/teeda/extension/html/impl/PageDescImpl.java =================================================================== --- teeda-extension/src/main/java/org/seasar/teeda/extension/html/impl/PageDescImpl.java (revision 4307) +++ teeda-extension/src/main/java/org/seasar/teeda/extension/html/impl/PageDescImpl.java (working copy) @@ -17,6 +17,7 @@ import java.io.File; import java.io.Serializable; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -72,6 +73,8 @@ private static final String[] EMPTY_SCOPES = new String[0]; + private Class pageClass; + public PageDescImpl(Class pageClass, String pageName) { this(pageClass, pageName, null); } @@ -90,6 +93,8 @@ } protected void setup(Class pageClass) { + this.pageClass = pageClass; + BeanDesc beanDesc = BeanDescFactory.getBeanDesc(pageClass); for (int i = 0; i < beanDesc.getPropertyDescSize(); ++i) { PropertyDesc pd = beanDesc.getPropertyDesc(i); @@ -172,6 +177,57 @@ return propertyNames.contains(name); } + public boolean hasNestProperty(String name) { + if( name == null ){ + return false; + } + + BeanDesc beanDesc = BeanDescFactory.getBeanDesc(pageClass); + String[] items = name.split("_"); + + if( items.length < 2 ){ + return false; + } + + for (int i = 0; i < beanDesc.getPropertyDescSize(); ++i) { + PropertyDesc pd = beanDesc.getPropertyDesc(i); + String propertyName = pd.getPropertyName(); + if( items[0].equals(propertyName) ){ + String[] items2 = new String[items.length-1]; + for( int j = 0 ; j < items.length-1; j++ ){ + items2[j] = items[j+1]; + } + return hasNestPropertySub( items2, pd.getPropertyType() ); + } + + } + + return false; + } + + private boolean hasNestPropertySub(String[] items,Class propertyClass) { + Field propertyFields[] = propertyClass.getDeclaredFields(); + + for( int i = 0 ; i < propertyFields.length ; i++ ){ + String fieldsName = propertyFields[i].getName(); + if( items[0].equals(fieldsName) ){ + if( items.length == 1 ){ + return true; + } else { + String[] items2 = new String[items.length-1]; + for( int j = 0 ; j < items.length-1; j++ ){ + items2[j] = items[j+1]; + } + Class fieldsClass = propertyFields[i].getType(); + + return hasNestPropertySub( items2, fieldsClass ); + } + } + } + + return false; + } + public boolean hasItemsProperty(String name) { return itemsPropertyNames.contains(name); } Index: teeda-extension/src/main/java/org/seasar/teeda/extension/html/PageDesc.java =================================================================== --- teeda-extension/src/main/java/org/seasar/teeda/extension/html/PageDesc.java (revision 4307) +++ teeda-extension/src/main/java/org/seasar/teeda/extension/html/PageDesc.java (working copy) @@ -24,6 +24,8 @@ boolean hasProperty(String name); + boolean hasNestProperty(String name); + /** * ForEach繧ТelectOneMenu縺ァ縺ョPage繧ッ繝ゥ繧ケ縺ォ謖√▽Collection縺後≠繧句?蜷医↓true繧定ソ斐☆. * @param name Index: teeda-extension/src/main/java/org/seasar/teeda/extension/html/factory/OutputTextFactory.java =================================================================== --- teeda-extension/src/main/java/org/seasar/teeda/extension/html/factory/OutputTextFactory.java (revision 4307) +++ teeda-extension/src/main/java/org/seasar/teeda/extension/html/factory/OutputTextFactory.java (working copy) @@ -67,6 +67,9 @@ if (isLabel(id, elementNode)) { return true; } + if (isNest(id, pageDesc)) { + return true; + } return pageDesc.hasProperty(id); } @@ -88,6 +91,11 @@ if (pageDesc.hasProperty(id)) { properties.put(JsfConstants.VALUE_ATTR, getBindingExpression( pageDesc.getPageName(), id)); + } else if( isNest(id, pageDesc) ){ + String[] items = id.split("_"); + String itemName = implode( items, "." ); + properties.put(JsfConstants.VALUE_ATTR, getBindingExpression( + pageDesc.getPageName(), itemName)); } else { final String key = toNormalizeId(id); TextNode firstTextNode = elementNode.getFirstTextNode(); @@ -96,6 +104,26 @@ } } + private static String implode(Object[] array, String sep) { + if (array == null) { + return null; + } else if (array.length < 1) { + return ""; + } else if (array.length < 2) { + return (array[0] != null) ? array[0].toString() : ""; + } + + StringBuffer buf = new StringBuffer( + (array[0] != null) ? array[0].toString() : ""); + + for (int i = 1; i < array.length; i++) { + buf.append(sep); + buf.append((array[i] != null) ? array[i].toString() : ""); + } + + return buf.toString(); + } + protected boolean isLabel(final String id, final ElementNode elementNode) { final String key = toNormalizeId(id); if (!TeedaExtensionConfiguration.getInstance().outputTextLabelUnderAnchorOnly) { @@ -115,6 +143,20 @@ } } + protected boolean isNest(final String id, PageDesc pageDesc) { + if( id == null ){ + return false; + } + + String[] items = id.split("_"); + + if( items.length < 2 ){ + return false; + } + + return pageDesc.hasNestProperty(id); + } + protected String toNormalizeId(String id) { final int pos = id.lastIndexOf('-'); if (pos >= 0) {