1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.seasar.remoting.common.interceptor;
47
48 import java.lang.reflect.Method;
49
50 import org.aopalliance.intercept.MethodInvocation;
51 import org.seasar.framework.aop.interceptors.AbstractInterceptor;
52 import org.seasar.framework.container.ComponentDef;
53 import org.seasar.framework.util.ClassUtil;
54 import org.seasar.framework.util.MethodUtil;
55 import org.seasar.remoting.common.connector.Connector;
56
57 /***
58 * リモートオブジェクトのメソッド呼び出しを行うためのインターセプタです。
59 * <p>
60 * このインターセプタはJavaインタフェースまたは抽象クラスに適用され、呼び出されたメソッドがターゲットによって実装されていない場合(抽象メソッド)に
61 * {@link Connector}に委譲することによりリモートオブジェクトのメソッド呼び出しを行います。
62 * <p>
63 * インターセプタはターゲットのコンポーネント定義から名前( <code><component></code> 要素の
64 * <code>name</code> 属性の値)を取得し、その名前をリモートオブジェクトの名前として {@link Connector#invoke}
65 * を呼び出します。コンポーネント定義に名前が定義されていない場合は、コンポーネントの型名( <code><component></code>
66 * 要素の <code>class</code> 属性の値)からパッケージ名を除いた名前をリモートオブジェクトの名前とします。
67 * コンポーネントの型名が定義されていない場合は、ターゲットオブジェクトのクラス名からパッケージ名を除いた名前をリモートオブジェクトの名前とします。
68 * もしプロパティ <code>remoteName</code>
69 * (オプション)が設定されていれば、その値が常にリモートオブジェクトの名前として使用されます。
70 *
71 * @see Connector
72 * @author koichik
73 */
74 public class RemotingInterceptor extends AbstractInterceptor {
75 protected Connector connector;
76 protected String remoteName;
77
78 /***
79 * リモート呼び出しを実行する {@link Connector}を設定します。このプロパティは必須です。
80 *
81 * @param connector
82 * リモート呼び出しを実行する {@link Connector}
83 */
84 public void setConnector(final Connector connector) {
85 this.connector = connector;
86 }
87
88 /***
89 * リモートオブジェクトの名前を設定します。このプロパティはオプションです。
90 * コンポーネント定義から取得できる名前を使うことが出来ない場合にのみ設定してください。
91 *
92 * @param remoteName
93 * リモートオブジェクトの名前
94 */
95 public void setRemoteName(final String remoteName) {
96 this.remoteName = remoteName;
97 }
98
99 /***
100 * ターゲットのメソッドが起動された時に呼び出されます。起動されたメソッドが抽象メソッドなら {@link Connector}に委譲します。
101 * 具象メソッドならターゲットのメソッドを呼び出します。
102 *
103 * @param invocation
104 * メソッドの起動情報
105 */
106 public Object invoke(final MethodInvocation invocation) throws Throwable {
107 final Method method = invocation.getMethod();
108 if (MethodUtil.isAbstract(method)) {
109 return connector.invoke(getRemoteName(invocation), method, invocation.getArguments());
110 }
111 return invocation.proceed();
112 }
113
114 /***
115 * リモートオブジェクトの名前を返します。リモートオブジェクトの名前は次の順で解決します。
116 * <ul>
117 * <li>プロパティ <code>remoteName</code> が設定されていればその値。</li>
118 * <li>コンポーネント定義に名前が設定されていればその値。</li>
119 * <li>コンポーネント定義に型が設定されていればその名前からパッケージ名を除いた値。</li>
120 * <li>ターゲットオブジェクトの型名からパッケージ名を除いた値。</li>
121 * </ul>
122 *
123 * @param invocation
124 * メソッドの起動情報
125 * @return リモートオブジェクトの名前
126 */
127 protected String getRemoteName(final MethodInvocation invocation) {
128 if (remoteName != null) {
129 return remoteName;
130 }
131
132 final ComponentDef componentDef = getComponentDef(invocation);
133 final String componentName = componentDef.getComponentName();
134 if (componentName != null) {
135 return componentName;
136 }
137
138 final Class componentClass = componentDef.getComponentClass();
139 if (componentClass != null) {
140 return ClassUtil.getShortClassName(componentClass);
141 }
142
143 return ClassUtil.getShortClassName(invocation.getThis().getClass());
144 }
145 }