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.ArrayList;
20  import java.util.List;
21  
22  import org.seasar.framework.util.MethodUtil;
23  import org.seasar.uruma.core.UrumaConstants;
24  import org.seasar.uruma.core.UrumaMessageCodes;
25  import org.seasar.uruma.log.UrumaLogger;
26  import org.seasar.uruma.util.AssertionUtil;
27  
28  /**
29   * オブジェクトに対するメソッドコールを実現するためのクラスです。<br />
30   * 
31   * @author y-komori
32   */
33  public class MethodBinding {
34      private static final UrumaLogger logger = UrumaLogger
35              .getLogger(MethodBinding.class);
36  
37      protected Object target;
38  
39      protected Method method;
40  
41      protected List<ArgumentsFilter> argumentsFilterList = new ArrayList<ArgumentsFilter>();
42  
43      protected MethodCallback callback;
44  
45      private String description;
46  
47      /**
48       * {@link MethodBinding} を構築します。<br />
49       * 
50       * @param target
51       *            ターゲットオブジェクト
52       * @param method
53       *            ターゲットメソッド
54       */
55      MethodBinding(final Object target, final Method method,
56              final MethodCallback callback) {
57          AssertionUtil.assertNotNull("target", target);
58          AssertionUtil.assertNotNull("method", method);
59  
60          this.target = target;
61          this.method = method;
62          this.description = UrumaLogger.getObjectDescription(target)
63                  + UrumaConstants.HASH_MARK + method.getName();
64          this.callback = callback;
65      }
66  
67      /**
68       * 引数なしでメソッドを実行します。<br />
69       * メソッド実行前に、
70       * {@link MethodBinding#addArgumentsFilter(ArgumentsFilter) addArgumentsFilter()}
71       * メソッドで追加された {@link ArgumentsFilter} が適用されます。
72       * 
73       * @return 戻り値オブジェクト
74       */
75      public Object invoke() {
76          return invoke(null);
77      }
78  
79      /**
80       * 引数を指定してメソッドを実行します。<br />
81       * メソッド実行前に、
82       * {@link MethodBinding#addArgumentsFilter(ArgumentsFilter) addArgumentsFilter()}
83       * メソッドで追加された {@link ArgumentsFilter} が適用されます。
84       * 
85       * @param args
86       *            引数オブジェクトの配列
87       * @return 戻り値オブジェクト
88       */
89      public Object invoke(final Object[] args) {
90          if (logger.isInfoEnabled()) {
91              logger.log(UrumaMessageCodes.START_METHOD_CALL, UrumaLogger
92                      .getObjectDescription(target), method.getName(), args);
93          }
94  
95          Object[] filteredArgs = args;
96          for (ArgumentsFilter filter : argumentsFilterList) {
97              filteredArgs = filter.filter(filteredArgs);
98          }
99          Object result = MethodUtil.invoke(method, target, filteredArgs);
100 
101         if (logger.isInfoEnabled()) {
102             logger.log(UrumaMessageCodes.END_METHOD_CALL, UrumaLogger
103                     .getObjectDescription(target), method.getName(), result);
104         }
105 
106         return callback(args, result);
107     }
108 
109     /**
110      * {@link ArgumentsFilter} を追加します。<br />
111      * 本メソッドで追加された {@link ArgumentsFilter} は
112      * {@link MethodBinding#invoke() invoke()} メソッド呼び出し時に、追加された順に適用されます。
113      * 
114      * @param argumentsFilter
115      *            {@link ArgumentsFilter} オブジェクト
116      */
117     public void addArgumentsFilter(final ArgumentsFilter argumentsFilter) {
118         this.argumentsFilterList.add(argumentsFilter);
119     }
120 
121     /**
122      * {@link Method} オブジェクトを取得します。<br />
123      * 
124      * @return {@link Method} オブジェクト
125      */
126     public Method getMethod() {
127         return this.method;
128     }
129 
130     /**
131      * ターゲットオブジェクトを取得します。<br />
132      * 
133      * @return ターゲットオブジェクト
134      */
135     public Object getTarget() {
136         return this.target;
137     }
138 
139     /**
140      * コールバックオブジェクトを設定します。<br />
141      * 
142      * @param callback
143      *            コールバックオブジェクト
144      */
145     public void setCallback(final MethodCallback callback) {
146         this.callback = callback;
147     }
148 
149     protected Object callback(final Object[] args, final Object returnValue) {
150         if (callback != null) {
151             return callback.callback(this, args, returnValue);
152         } else {
153             return returnValue;
154         }
155     }
156 
157     /*
158      * @see java.lang.Object#toString()
159      */
160     @Override
161     public String toString() {
162         return this.description;
163     }
164 }