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 java.lang.reflect.Method;
19  import java.util.List;
20  import java.util.Set;
21  
22  import org.seasar.uruma.annotation.EventListener;
23  import org.seasar.uruma.context.PartContext;
24  import org.seasar.uruma.context.WidgetHandle;
25  import org.seasar.uruma.context.WindowContext;
26  import org.seasar.uruma.core.UrumaMessageCodes;
27  import org.seasar.uruma.desc.PartActionDesc;
28  import org.seasar.uruma.exception.UnsupportedClassException;
29  import org.seasar.uruma.exception.WidgetNotFoundException;
30  import org.seasar.uruma.log.UrumaLogger;
31  
32  /**
33   * メソッドバインディングの生成をサポートするクラスです。</br>
34   * 
35   * @author y-komori
36   */
37  public class MethodBindingSupport implements UrumaMessageCodes {
38      private static final UrumaLogger logger = UrumaLogger
39              .getLogger(MethodBindingSupport.class);
40  
41      /**
42       * 指定された {@link WindowContext} 配下のすべての {@link PartContext} に対して、 {@link
43       * #createListeners(PartContext)} メソッドを実行します。<br />
44       * 
45       * @param context
46       *            {@link WindowContext} オブジェクト
47       */
48      public static void createAllListeners(final WindowContext context) {
49          createListeners((PartContext) context);
50          for (PartContext partContext : context.getPartContextList()) {
51              createListeners(partContext);
52          }
53      }
54  
55      /**
56       * 指定された {@link PartContext} のパートアクションコンポーネントに対して、メソッドバインディングを生成します。<br />
57       * <p>
58       * 本メソッドでは、以下の手順でメソッドバインディングを行います。
59       * <ol>
60       * <li>ウィンドウに対応するアクションコンポーネント(「<i>ウィンドウ名</i>Action」
61       * という名前のコンポーネント)をコンテナから検索します。
62       * <li>コンポーネントが見つかった場合、 そのコンポーネントで {@link EventListener}
63       * アノテーションを持つメソッドを探します。
64       * <li>見つかった各メソッドに対して、メソッド名と同じ id を持つウィジットを {@link PartContext} から探します。
65       * <li>ウィジットが見つかれば、リスナを生成してウィジット上でアクションが発生した際に、
66       * アノテーションが付加されたメソッドを呼び出すように設定します。
67       * </ol>
68       * </p>
69       * 
70       * @param context
71       *            {@link PartContext} オブジェクト
72       */
73      public static void createListeners(final PartContext context) {
74          Object actionObj = context.getPartActionObject();
75          if (actionObj != null) {
76              PartActionDesc actionDesc = context.getPartActionDesc();
77  
78              List<EventListenerDef> eDefList = actionDesc
79                      .getEventListenerDefList();
80              for (EventListenerDef def : eDefList) {
81                  createListener(context, def);
82              }
83          }
84      }
85  
86      private static void createListener(final PartContext context,
87              final EventListenerDef def) {
88          Method targetMethod = def.getTargetMethod();
89  
90          String[] ids = def.getId();
91          for (String id : ids) {
92              // すべてのコンテクストから id にマッチする WidgetHandle を検索
93              Set<WidgetHandle> handles = context.getWindowContext()
94                      .findWidgetHandles(id);
95  
96              if (handles.size() > 0) {
97                  // 見つかった各 WidgetHandle に対してリスナを設定
98                  for (WidgetHandle handle : handles) {
99                      ListenerBinder binder = ListenerBinderFactory
100                             .getListenerBinder(handle, def.getType());
101 
102                     bindMethod(binder, id, handle, context, def);
103                 }
104             } else {
105                 String className = targetMethod.getDeclaringClass().getName();
106                 throw new WidgetNotFoundException(id, className);
107             }
108         }
109     }
110 
111     private static void bindMethod(final ListenerBinder binder,
112             final String id, final WidgetHandle handle,
113             final PartContext context, final EventListenerDef def) {
114         if (binder != null) {
115             MethodBinding binding = MethodBindingFactory.createMethodBinding(
116                     context.getPartActionObject(), def.getTargetMethod(),
117                     handle, def.getAsyncMethod());
118             Class<?> listenerClass = binder.bindListener(handle, context,
119                     binding, def);
120 
121             if (logger.isDebugEnabled()) {
122                 logger.log(CREATE_METHOD_BINDING, id, def.getType(), binding,
123                         listenerClass.getName());
124             }
125         } else {
126             throw new UnsupportedClassException(handle.getWidgetClass());
127         }
128     }
129 }