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 }