View Javadoc

1   /*
2    *
3    * The Seasar Software License, Version 1.1
4    *
5    * Copyright (c) 2003-2004 The Seasar Project. All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or
8    * without modification, are permitted provided that the following
9    * conditions are met:
10   *
11   * 1. Redistributions of source code must retain the above
12   *    copyright notice, this list of conditions and the following
13   *    disclaimer.
14   *
15   * 2. Redistributions in binary form must reproduce the above
16   *    copyright notice, this list of conditions and the following
17   *    disclaimer in the documentation and/or other materials provided
18   *    with the distribution.
19   *
20   * 3. The end-user documentation included with the redistribution,
21   *    if any, must include the following acknowledgement:
22   *    "This product includes software developed by the
23   *    Seasar Project (http://www.seasar.org/)."
24   *    Alternately, this acknowledgement may appear in the software
25   *    itself, if and wherever such third-party acknowledgements
26   *    normally appear.
27   *
28   * 4. Neither the name "The Seasar Project" nor the names of its
29   *    contributors may be used to endorse or promote products derived
30   *    from this software without specific prior written permission of
31   *    the Seasar Project.
32   *
33   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR
34   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE SEASAR PROJECT
37   * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
38   * INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42   * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING
43   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
44   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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>&lt;component&gt;</code> 要素の
64   * <code>name</code> 属性の値)を取得し、その名前をリモートオブジェクトの名前として {@link Connector#invoke}
65   * を呼び出します。コンポーネント定義に名前が定義されていない場合は、コンポーネントの型名( <code>&lt;component&gt;</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 }