View Javadoc

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.rcp.binding;
17  
18  import java.lang.reflect.Method;
19  
20  import org.eclipse.jface.viewers.ISelection;
21  import org.eclipse.jface.viewers.IStructuredSelection;
22  import org.eclipse.ui.ISelectionListener;
23  import org.eclipse.ui.IWorkbenchPart;
24  import org.seasar.uruma.binding.method.MethodBinding;
25  import org.seasar.uruma.binding.method.MethodCallback;
26  import org.seasar.uruma.binding.method.SingleParamTypeMethodBinding;
27  import org.seasar.uruma.binding.value.ValueBindingSupport;
28  import org.seasar.uruma.binding.widget.WidgetBinder;
29  import org.seasar.uruma.context.PartContext;
30  import org.seasar.uruma.context.WindowContext;
31  import org.seasar.uruma.core.UrumaMessageCodes;
32  import org.seasar.uruma.log.UrumaLogger;
33  import org.seasar.uruma.util.AssertionUtil;
34  
35  /**
36   * 任意のメソッドを呼び出すことができる、汎用的な {@link ISelectionListener} の実装クラスです。<br />
37   * <p>
38   * 本クラスは {@link ISelectionListener} として振る舞い、 <code>selectionChanged</code>
39   * メソッドが呼び出された際に、コンストラクタで渡される {@link Object}、{@link Method} の表すメソッドを呼び出します。<br />
40   * このとき、コンストラクタで渡される {@link Method} オブジェクトの表す引数によって、呼び出される際の引数の渡し方が変化します。<br />
41   * <dl>
42   * <dt>引数がなしのとき
43   * <dd>引数には何も渡されません。
44   * <dt>引数が配列型以外で 1 個のとき
45   * <dd><code>selectionChanged</code> メソッドで渡される {@link ISelection}
46   * オブジェクトの持つ要素が引数の型に代入可能かチェックし、代入可能ならば最初の 1 個を渡します。
47   * <dt>引数が配列型で 1 個のとき
48   * <dd><code>selectionChanged</code> メソッドで渡される {@link ISelection}
49   * オブジェクトの持つ要素が引数の型に代入可能かチェックし、代入可能ならば全ての要素を渡します。
50   * <dt>引数が 2 個以上のとき
51   * <dd>コンストラクタ呼び出し時に {@link IllegalArgumentException} をスローします。
52   * </dl>
53   * </p>
54   * 
55   * @author y-komori
56   */
57  public class GenericSelectionListener implements ISelectionListener,
58          MethodCallback {
59      private static final UrumaLogger logger = UrumaLogger
60              .getLogger(GenericSelectionListener.class);
61  
62      private PartContext context;
63  
64      private SingleParamTypeMethodBinding methodBinding;
65  
66      /**
67       * {@link GenericSelectionListener} を構築します。<br />
68       * 
69       * @param context
70       *            {@link PartContext} オブジェクト
71       * @param methodBinding
72       *            呼び出し対象の {@link SingleParamTypeMethodBinding} オブジェクト
73       */
74      public GenericSelectionListener(final PartContext context,
75              final SingleParamTypeMethodBinding methodBinding) {
76          AssertionUtil.assertNotNull("context", context);
77          AssertionUtil.assertNotNull("methodBinding", methodBinding);
78  
79          this.context = context;
80          this.methodBinding = methodBinding;
81          this.methodBinding.setCallback(this);
82      }
83  
84      /**
85       * イベント処理を行います。<br />
86       * <p>
87       * 本メソッドでは、以下の処理を順に実行します。<br />
88       * <ol>
89       * <li> {@link WindowContext} へフォームオブジェクトとして、
90       * {@link SingleParamTypeMethodBinding} の保持するターゲットオブジェクトを設定します。<br />
91       * <li>ターゲットオブジェクトへ、画面の選択状態をバインド(ImportSelection)します。<br />
92       * <li>ターゲットオブジェクトへ、画面の値をバインド(ImportValue)します。<br />
93       * <li>コンストラクタで指定された {@link MethodBinding} の呼び出しを行います。<br />
94       * <li>画面へ、ターゲットオブジェクトの値をバインド(ExportValue)します。<br />
95       * <li>画面の選択状態ををターゲットオブジェクトのフィールドに従ってバインド(ExportSelection)します。<br />
96       * </ol>
97       * </p>
98       * 
99       * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart,
100      *      org.eclipse.jface.viewers.ISelection)
101      */
102     public void selectionChanged(final IWorkbenchPart part,
103             final ISelection selection) {
104         try {
105             if (selection instanceof IStructuredSelection) {
106                 IStructuredSelection structuredSelection = (IStructuredSelection) selection;
107                 Object[] selectedModels = structuredSelection.toArray();
108                 if (selectedModels.length > 0) {
109 
110                     WidgetBinder
111                             .bindWidgets(methodBinding.getTarget(), context);
112 
113                     ValueBindingSupport.importSelection(context);
114                     ValueBindingSupport.importValue(context);
115 
116                     methodBinding.invoke(selectedModels);
117                 }
118             }
119         } catch (Throwable ex) {
120             logger.log(UrumaMessageCodes.EXCEPTION_OCCURED_INVOKING_METHOD,
121                     methodBinding.toString());
122             logger.log(ex);
123         }
124     }
125 
126     /*
127      * @see org.seasar.uruma.binding.method.MethodCallback#callback(org.seasar.uruma.binding.method.MethodBinding,
128      *      java.lang.Object[], java.lang.Object)
129      */
130     public Object callback(final MethodBinding binding, final Object[] args,
131             final Object returnValue) {
132         ValueBindingSupport.exportValue(context);
133         ValueBindingSupport.exportSelection(context);
134         return returnValue;
135     }
136 }