Coverage Report - org.seasar.uruma.binding.value.binder.AbstractValueBinder
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractValueBinder
55%
48/87
38%
16/42
0
 
 1  
 /*
 2  
  * Copyright 2004-2008 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.uruma.binding.value.binder;
 17  
 
 18  
 import java.lang.reflect.Array;
 19  
 import java.util.ArrayList;
 20  
 import java.util.List;
 21  
 
 22  
 import org.eclipse.jface.viewers.IBaseLabelProvider;
 23  
 import org.eclipse.jface.viewers.IContentProvider;
 24  
 import org.eclipse.jface.viewers.IStructuredSelection;
 25  
 import org.eclipse.jface.viewers.StructuredSelection;
 26  
 import org.eclipse.jface.viewers.StructuredViewer;
 27  
 import org.eclipse.jface.viewers.Viewer;
 28  
 import org.seasar.framework.beans.PropertyDesc;
 29  
 import org.seasar.uruma.binding.value.ValueBinder;
 30  
 import org.seasar.uruma.component.UIComponent;
 31  
 import org.seasar.uruma.core.UrumaConstants;
 32  
 import org.seasar.uruma.core.UrumaMessageCodes;
 33  
 import org.seasar.uruma.exception.BindingException;
 34  
 import org.seasar.uruma.log.UrumaLogger;
 35  
 import org.seasar.uruma.util.AssertionUtil;
 36  
 import org.seasar.uruma.viewer.ContentsHolder;
 37  
 import org.seasar.uruma.viewer.TargetClassHoldingProvider;
 38  
 
 39  
 /**
 40  
  * {@link ValueBinder} のための基底クラスです。<br />
 41  
  * 
 42  
  * @param <WIDGET_TYPE>
 43  
  *            対応するウィジットの型
 44  
  * @author y-komori
 45  
  */
 46  
 public abstract class AbstractValueBinder<WIDGET_TYPE> implements ValueBinder {
 47  40
     private UrumaLogger logger = UrumaLogger.getLogger(getClass());
 48  
 
 49  
     private Class<WIDGET_TYPE> widgetType;
 50  
 
 51  
     protected static final String IMPORT_VALUE = "[ImportValue]";
 52  
 
 53  
     protected static final String EXPORT_VALUE = "[ExportValue]";
 54  
 
 55  
     protected static final String IMPORT_SELECTION = "[ImportSelection]";
 56  
 
 57  
     protected static final String EXPORT_SELECTION = "[ExportSelection]";
 58  
 
 59  
     /**
 60  
      * {@link AbstractValueBinder} を構築します。<br />
 61  
      * 
 62  
      * @param widgetType
 63  
      *            ウィジットの型
 64  
      */
 65  40
     public AbstractValueBinder(final Class<WIDGET_TYPE> widgetType) {
 66  40
         AssertionUtil.assertNotNull("widgetType", widgetType);
 67  40
         this.widgetType = widgetType;
 68  40
     }
 69  
 
 70  
     /*
 71  
      * @see org.seasar.uruma.binding.value.ValueBinder#importValue(java.lang.Object,
 72  
      *      java.lang.Object, org.seasar.framework.beans.PropertyDesc)
 73  
      */
 74  
     public void importValue(final Object widget, final Object formObj,
 75  
             final PropertyDesc propDesc, final UIComponent uiComp) {
 76  0
         doImportValue(getWidgetType().cast(widget), formObj, propDesc, uiComp);
 77  0
     }
 78  
 
 79  
     /*
 80  
      * @see org.seasar.uruma.binding.value.ValueBinder#exportValue(java.lang.Object,
 81  
      *      java.lang.Object, org.seasar.framework.beans.PropertyDesc)
 82  
      */
 83  
     public void exportValue(final Object widget, final Object formObj,
 84  
             final PropertyDesc propDesc, final UIComponent uiComp) {
 85  32
         doExportValue(getWidgetType().cast(widget), formObj, propDesc, uiComp);
 86  32
     }
 87  
 
 88  
     /*
 89  
      * @see org.seasar.uruma.binding.value.ValueBinder#importSelection(java.lang.Object,
 90  
      *      java.lang.Object, org.seasar.framework.beans.PropertyDesc)
 91  
      */
 92  
     public void importSelection(final Object widget, final Object formObj,
 93  
             final PropertyDesc propDesc, final UIComponent uiComp) {
 94  0
         doImportSelection(getWidgetType().cast(widget), formObj, propDesc,
 95  
                 uiComp);
 96  0
     }
 97  
 
 98  
     /*
 99  
      * @see org.seasar.uruma.binding.value.ValueBinder#exportSelection(java.lang.Object,
 100  
      *      java.lang.Object, org.seasar.framework.beans.PropertyDesc)
 101  
      */
 102  
     public void exportSelection(final Object widget, final Object formObj,
 103  
             final PropertyDesc propDesc, final UIComponent uiComp) {
 104  4
         doExportSelection(getWidgetType().cast(widget), formObj, propDesc,
 105  
                 uiComp);
 106  4
     }
 107  
 
 108  
     /*
 109  
      * @see org.seasar.uruma.binding.value.ValueBinder#getWidgetType()
 110  
      */
 111  
     public Class<WIDGET_TYPE> getWidgetType() {
 112  76
         return this.widgetType;
 113  
     }
 114  
 
 115  
     /**
 116  
      * ウィジットの値をフォームへ設定します。<br />
 117  
      * 本メソッドをサブクラスでオーバーライドしてください。<br />
 118  
      * デフォルトでは何も行いません。
 119  
      * 
 120  
      * @param widget
 121  
      *            ウィジット側オブジェクト
 122  
      * @param formObj
 123  
      *            フォーム側オブジェクト
 124  
      * @param propDesc
 125  
      *            フォーム側のプロパティを表す {@link PropertyDesc} オブジェクト
 126  
      * @param uiComp
 127  
      *            コンポーネント
 128  
      */
 129  
     protected void doImportValue(final WIDGET_TYPE widget,
 130  
             final Object formObj, final PropertyDesc propDesc,
 131  
             final UIComponent uiComp) {
 132  
 
 133  0
     }
 134  
 
 135  
     /**
 136  
      * フォームの値をウィジットへ設定します。<br />
 137  
      * デフォルトでは、 <code>widget</code> が {@link StructuredViewer}
 138  
      * のサブクラスかつコンテンツプロバイダが {@link ContentsHolder} の実装クラスである場合に、
 139  
      * <code>propDesc</code> の持つ値をコンテンツプロバイダへ設定します。<br />
 140  
      * デフォルト処理をカスタマイズしたい場合は、サブクラスでオーバーライドしてください。<br />
 141  
      * 
 142  
      * @param widget
 143  
      *            ウィジット側オブジェクト
 144  
      * @param formObj
 145  
      *            フォーム側オブジェクト
 146  
      * @param propDesc
 147  
      *            フォーム側のプロパティを表す {@link PropertyDesc} オブジェクト
 148  
      * @param uiComp
 149  
      *            コンポーネント
 150  
      */
 151  
     protected void doExportValue(final WIDGET_TYPE widget,
 152  
             final Object formObj, final PropertyDesc propDesc,
 153  
             final UIComponent uiComp) {
 154  20
         if (widget instanceof StructuredViewer) {
 155  20
             StructuredViewer viewer = StructuredViewer.class.cast(widget);
 156  
 
 157  20
             Class<?> formFieldType = propDesc.getField().getType();
 158  20
             Object contents = propDesc.getValue(formObj);
 159  20
             IContentProvider contentProvider = viewer.getContentProvider();
 160  20
             IBaseLabelProvider labelProvider = viewer.getLabelProvider();
 161  
 
 162  20
             if (contentProvider != null
 163  
                     && contentProvider instanceof ContentsHolder) {
 164  20
                 ContentsHolder holder = (ContentsHolder) contentProvider;
 165  20
                 if (formFieldType.isArray()) {
 166  4
                     if (contents != null) {
 167  4
                         holder.setContents((Object[]) contents);
 168  
                     } else {
 169  0
                         holder.setContents(new Object[] {});
 170  
                     }
 171  4
                     setClassToProvider(labelProvider, formFieldType
 172  
                             .getComponentType());
 173  16
                 } else if (List.class.isAssignableFrom(formFieldType)) {
 174  12
                     List<?> listContents = (List<?>) contents;
 175  
 
 176  12
                     if ((listContents != null) && (listContents.size() > 0)) {
 177  12
                         holder.setContents(listContents);
 178  
 
 179  12
                         Object content = listContents.get(0);
 180  12
                         setClassToProvider(labelProvider, content.getClass());
 181  12
                     } else {
 182  0
                         holder.setContents(new ArrayList<Object>());
 183  0
                         setClassToProvider(labelProvider, Object.class);
 184  
                     }
 185  12
                 } else {
 186  4
                     if (contents != null) {
 187  4
                         holder.setContents(new Object[] { contents });
 188  4
                         setClassToProvider(labelProvider, contents.getClass());
 189  
                     } else {
 190  0
                         holder.setContents(new Object[] {});
 191  0
                         setClassToProvider(labelProvider, Object.class);
 192  
                     }
 193  
                 }
 194  
 
 195  20
                 logBinding(EXPORT_VALUE, formObj, propDesc, widget, null,
 196  
                         contents);
 197  
 
 198  20
                 viewer.setInput(contents);
 199  
             }
 200  
         }
 201  20
     }
 202  
 
 203  
     /**
 204  
      * ウィジットで選択されているオブジェクトをフォームへ設定します。<br />
 205  
      * デフォルトでは、 <code>widget</code> が {@link Viewer} のサブクラスである場合に
 206  
      * <code>propDesc</code> の表すプロパティにビューアから取得した選択中オブジェクトを設定します。<br />
 207  
      * デフォルト処理をカスタマイズしたい場合は、サブクラスでオーバーライドしてください。<br />
 208  
      * 
 209  
      * @param widget
 210  
      *            ウィジット側オブジェクト
 211  
      * @param formObj
 212  
      *            フォーム側オブジェクト
 213  
      * @param propDesc
 214  
      *            フォーム側のプロパティを表す {@link PropertyDesc} オブジェクト
 215  
      * @param uiComp
 216  
      *            コンポーネント
 217  
      * @throws BindingException
 218  
      *             ビューアで選択させれているオブジェクトの型とプロパティの型が一致しなかった場合
 219  
      */
 220  
     protected void doImportSelection(final WIDGET_TYPE widget,
 221  
             final Object formObj, final PropertyDesc propDesc,
 222  
             final UIComponent uiComp) {
 223  0
         if (widget instanceof Viewer) {
 224  0
             Viewer viewer = Viewer.class.cast(widget);
 225  
 
 226  0
             IStructuredSelection selection = (IStructuredSelection) viewer
 227  
                     .getSelection();
 228  0
             int size = selection.size();
 229  0
             if (size > 0) {
 230  0
                 Class<?> propertyType = propDesc.getPropertyType();
 231  0
                 Object firstElement = selection.getFirstElement();
 232  0
                 if (propertyType.isArray()) {
 233  0
                     Object[] selectedArray = selection.toArray();
 234  0
                     Object content = Array.newInstance(propertyType
 235  
                             .getComponentType(), selectedArray.length);
 236  0
                     System.arraycopy(selectedArray, 0, content, 0,
 237  
                             selectedArray.length);
 238  
 
 239  0
                     logBinding(IMPORT_SELECTION, widget, null, formObj,
 240  
                             propDesc, content);
 241  0
                     propDesc.setValue(formObj, content);
 242  0
                 } else if (propertyType.isAssignableFrom(List.class)) {
 243  0
                     List<?> list = selection.toList();
 244  0
                     logBinding(IMPORT_SELECTION, widget, null, formObj,
 245  
                             propDesc, list);
 246  0
                     propDesc.setValue(formObj, list);
 247  0
                 } else if (propertyType.isAssignableFrom(firstElement
 248  
                         .getClass())) {
 249  0
                     logBinding(IMPORT_SELECTION, widget, null, formObj,
 250  
                             propDesc, firstElement);
 251  0
                     propDesc.setValue(formObj, firstElement);
 252  
                 } else {
 253  0
                     throw new BindingException(
 254  
                             UrumaMessageCodes.CLASS_NOT_MUTCH, formObj
 255  
                                     .getClass().getName(), propDesc
 256  
                                     .getPropertyName());
 257  
                 }
 258  
             }
 259  
         }
 260  0
     }
 261  
 
 262  
     /**
 263  
      * フォームの持つオブジェクトをウィジットの選択状態として設定します。<br />
 264  
      * デフォルトでは、 <code>widget</code> が {@link Viewer} のサブクラスである場合に
 265  
      * <code>propDesc</code> の持つ値を {@link StructuredSelection}
 266  
      * にラップしてビューアに設定します。<br />
 267  
      * デフォルト処理をカスタマイズしたい場合は、サブクラスでオーバーライドしてください。<br />
 268  
      * 
 269  
      * @param widget
 270  
      *            ウィジット側オブジェクト
 271  
      * @param formObj
 272  
      *            フォーム側オブジェクト
 273  
      * @param propDesc
 274  
      *            フォーム側のプロパティを表す {@link PropertyDesc} オブジェクト
 275  
      * @param uiComp
 276  
      *            コンポーネント
 277  
      */
 278  
     protected void doExportSelection(final WIDGET_TYPE widget,
 279  
             final Object formObj, final PropertyDesc propDesc,
 280  
             final UIComponent uiComp) {
 281  4
         if (widget instanceof Viewer) {
 282  4
             Viewer viewer = Viewer.class.cast(widget);
 283  4
             Object selection = propDesc.getValue(formObj);
 284  4
             if (selection != null) {
 285  4
                 logBinding(EXPORT_SELECTION, formObj, propDesc, viewer, null,
 286  
                         selection);
 287  
 
 288  4
                 viewer.setSelection(new StructuredSelection(selection), true);
 289  
             }
 290  
         }
 291  4
     }
 292  
 
 293  
     protected void setClassToProvider(final IBaseLabelProvider provider,
 294  
             final Class<?> clazz) {
 295  20
         if ((provider != null)
 296  
                 && (provider instanceof TargetClassHoldingProvider)) {
 297  20
             TargetClassHoldingProvider.class.cast(provider).setTargetClass(
 298  
                     clazz);
 299  
         }
 300  20
     }
 301  
 
 302  
     /**
 303  
      * バインディングの状況をログ出力します。<br />
 304  
      * 
 305  
      * @param command
 306  
      *            コマンド文字列
 307  
      * @param srcObj
 308  
      *            バインド元オブジェクト
 309  
      * @param srcProp
 310  
      *            バインド元プロパティ
 311  
      * @param destObj
 312  
      *            バインド先オブジェクト
 313  
      * @param destProp
 314  
      *            バインド先オブジェクト
 315  
      * @param value
 316  
      *            値
 317  
      */
 318  
     protected void logBinding(final String command, final Object srcObj,
 319  
             final PropertyDesc srcProp, final Object destObj,
 320  
             final PropertyDesc destProp, final Object value) {
 321  36
         if (logger.isInfoEnabled()) {
 322  0
             String srcName = UrumaConstants.NULL_STRING;
 323  0
             if (srcProp != null) {
 324  0
                 srcName = srcProp.getPropertyName();
 325  
             }
 326  0
             String destName = UrumaConstants.NULL_STRING;
 327  0
             if (destProp != null) {
 328  0
                 destName = destProp.getPropertyName();
 329  
             }
 330  0
             logger.log(UrumaMessageCodes.DO_BINDING, command, UrumaLogger
 331  
                     .getObjectDescription(srcObj), srcName, UrumaLogger
 332  
                     .getObjectDescription(destObj), destName, value);
 333  
         }
 334  36
     }
 335  
 }