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.binding.method;
17  
18  import org.eclipse.swt.events.TypedEvent;
19  import org.eclipse.swt.widgets.Event;
20  import org.seasar.uruma.binding.value.ValueBindingSupport;
21  import org.seasar.uruma.binding.widget.WidgetBinder;
22  import org.seasar.uruma.context.PartContext;
23  import org.seasar.uruma.log.UrumaLogger;
24  import org.seasar.uruma.util.AssertionUtil;
25  
26  /**
27   * {@link MethodBinding} を使用してメソッドを呼び出す汎用リスナのための基底クラスです。<br />
28   * 
29   * @author y-komori
30   */
31  public abstract class AbstractGenericListener implements MethodCallback {
32      private static final UrumaLogger logger = UrumaLogger
33              .getLogger(AbstractGenericListener.class);
34  
35      protected PartContext context;
36  
37      protected MethodBinding methodBinding;
38  
39      AbstractGenericListener(final PartContext context,
40              final MethodBinding methodBinding) {
41          AssertionUtil.assertNotNull("context", context);
42          AssertionUtil.assertNotNull("methodBinding", methodBinding);
43          this.methodBinding = methodBinding;
44          this.context = context;
45          this.methodBinding.setCallback(this);
46      }
47  
48      /**
49       * {@link MethodBinding} に対する呼び出しを行います。<br />
50       * 
51       * @return メソッドの戻り値。メソッドの呼び出し中に例外が発生した場合は <code>null</code>。
52       */
53      protected Object invokeMethod() {
54          return invokeMethod(null);
55      }
56  
57      /**
58       * {@link MethodBinding} に対する呼び出しを行います。<br />
59       * 
60       * <p>
61       * 本メソッドでは、以下の処理を順に実行します。<br />
62       * <ol>
63       * <li>ターゲットオブジェクトへ、画面上のウィジットをバインドします。<br />
64       * <li>ターゲットオブジェクトへ、画面の選択状態をバインド(ImportSelection)します。<br />
65       * <li>ターゲットオブジェクトへ、画面の値をバインド(ImportValue)します。<br />
66       * <li>コンストラクタで指定された {@link MethodBinding} の呼び出しを行います。<br />
67       * <li>画面へ、ターゲットオブジェクトの値をバインド(ExportValue)します。<br />
68       * <li>画面の選択状態ををターゲットオブジェクトのフィールドに従ってバインド(ExportSelection)します。<br />
69       * </ol>
70       * </p>
71       * 
72       * @param event
73       *            イベントオブジェクト
74       * @return メソッドの戻り値。メソッドの呼び出し中に例外が発生した場合は <code>null</code>。
75       */
76      protected Object invokeMethod(final Object event) {
77          if (checkLoop()) {
78              return null;
79          }
80  
81          try {
82              WidgetBinder.bindWidgets(methodBinding.getTarget(), context);
83  
84              ValueBindingSupport.importSelection(context);
85              ValueBindingSupport.importValue(context);
86  
87              Object result = methodBinding.invoke(new Object[] { event });
88  
89              return result;
90          } catch (Throwable ex) {
91              logger.log(ex);
92              return null;
93          }
94      }
95  
96      /*
97       * @see org.seasar.uruma.binding.method.MethodCallback#callback(org.seasar.uruma.binding.method.MethodBinding,
98       *      java.lang.Object[], java.lang.Object)
99       */
100     public Object callback(final MethodBinding binding, final Object[] args,
101             final Object returnValue) {
102         Object event = null;
103         if (args != null && args.length > 0) {
104             event = args[0];
105         }
106         if (!isDisposed(event)) {
107             ValueBindingSupport.exportValue(context);
108             ValueBindingSupport.exportSelection(context);
109         }
110         return returnValue;
111     }
112 
113     protected boolean isDisposed(final Object event) {
114         if (event != null) {
115             if (event instanceof Event) {
116                 return ((Event) event).widget.isDisposed();
117             } else if (event instanceof TypedEvent) {
118                 return ((TypedEvent) event).widget.isDisposed();
119             }
120         }
121         return false;
122     }
123 
124     protected boolean checkLoop() {
125         StackTraceElement elements[] = Thread.currentThread().getStackTrace();
126         if (elements != null) {
127             int count = 0;
128             String myClassName = getClass().getName();
129             for (StackTraceElement element : elements) {
130                 if (myClassName.equals(element.getClassName())) {
131                     count++;
132                     if (count > 1) {
133                         return true;
134                     }
135                 }
136             }
137         }
138         return false;
139     }
140 
141 }