[Jiemamy-notify:2805] commit [3729] AOP Alliance対応の準備

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2009年 10月 8日 (木) 03:49:11 JST


Revision: 3729
          http://sourceforge.jp/projects/jiemamy/svn/view?view=rev&revision=3729
Author:   ashigeru
Date:     2009-10-08 03:49:11 +0900 (Thu, 08 Oct 2009)

Log Message:
-----------
AOP Alliance対応の準備

Modified Paths:
--------------
    leto/factory-enhancer/branches/interface-enhancer/pom.xml
    leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/Invocation.java
    leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/InvocationPointcut.java
    leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/Main.java

Added Paths:
-----------
    leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/
    leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/AopAllianceDriver.java
    leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/ProxyDriver.java

Removed Paths:
-------------
    leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ProxyDriver.java

Modified: leto/factory-enhancer/branches/interface-enhancer/pom.xml
===================================================================
--- leto/factory-enhancer/branches/interface-enhancer/pom.xml	2009-10-07 18:16:38 UTC (rev 3728)
+++ leto/factory-enhancer/branches/interface-enhancer/pom.xml	2009-10-07 18:49:11 UTC (rev 3729)
@@ -65,6 +65,12 @@
       <artifactId>javassist</artifactId>
       <version>3.8.0.GA</version>
     </dependency>
+    <dependency>
+      <groupId>aopalliance</groupId>
+      <artifactId>aopalliance</artifactId>
+      <version>1.0</version>
+      <optional>true</optional>
+    </dependency>
      <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>

Modified: leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/Invocation.java
===================================================================
--- leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/Invocation.java	2009-10-07 18:16:38 UTC (rev 3728)
+++ leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/Invocation.java	2009-10-07 18:49:11 UTC (rev 3729)
@@ -26,17 +26,22 @@
 public interface Invocation {
 	
 	/**
-	 * 拡張を行う前の本来の呼び出し、またはインスタンス生成を続行する。
+	 * 拡張を行う前の本来のメソッド起動、またはインスタンス生成を続行する。
 	 * <p>
-	 * このメソッドが返す値は、本来のメソッド呼び出しを実行した際の戻り値である。
+	 * このメソッドが返す値は、本来のメソッドを起動した際の戻り値である。
 	 * ただし、戻り値の型がプリミティブ型である場合はそのラッパー型での表現を返し、
 	 * {@code void}型である場合には{@code null}を常に返す。
 	 * また、このオブジェクトがインスタンス生成を表す場合には、この呼び出しは実際に生成されたインスタンスを返す。
 	 * </p>
 	 * <p>
-	 * 本来の呼び出しを実行した際にその呼び出し先で何らかの例外が発生した場合、
+	 * 本来の起動を実行した際にその呼び出し先で何らかの例外が発生した場合、
 	 * このメソッドはその例外を{@link InvocationTargetException}でラップした例外をスローする。
 	 * </p>
+	 * <p>
+	 * なお、起動する対象が存在しない場合、{@link InvocationTargetException}がスローされるが
+	 * その原因となる例外は{@link IncompatibleClassChangeError}を親とするクラスのインスタンスである。
+	 * たとえば、実装されてないインターフェースメソッドを起動した場合、{@link AbstractMethodError}が該当する。
+	 * </p>
 	 * @return
 	 *      メソッド呼び出し、またはインスタンス生成の結果。
 	 *      ただし、{@code void}型のメソッドを呼び出した場合には{@code null}、または

Modified: leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/InvocationPointcut.java
===================================================================
--- leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/InvocationPointcut.java	2009-10-07 18:16:38 UTC (rev 3728)
+++ leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/InvocationPointcut.java	2009-10-07 18:49:11 UTC (rev 3729)
@@ -17,6 +17,7 @@
 
 import javassist.CtBehavior;
 import javassist.CtClass;
+import javassist.CtMethod;
 
 /**
  * このエンハンサにおいて、拡張する対象のメソッド呼び出しおよび
@@ -55,6 +56,33 @@
 	 * そうでなく、インスタンス生成に対して検査を行う場合、引数の値は必ず
 	 * {@link javassist.CtConstructor CtConstructor}型となる。
 	 * </p>
+	 * <p>
+	 * なお、このポイントカットに対する{@link InvocationHandler ハンドラ}のメソッド
+	 * {@link InvocationHandler#handle(Invocation)}は、次の要件を満たす必要がある。
+	 * </p>
+	 * <ul>
+	 * <li> メソッド起動に対するハンドラ
+	 *   <ul>
+	 *   <li>
+	 *   {@link CtMethod#getReturnType() ((CtMethod) behavior).getReturnType()}
+	 *   が{@code void}を表現する場合、どのような制約も課されない。
+	 *   </li>
+	 *   <li>
+	 *   {@link CtMethod#getReturnType() ((CtMethod) behavior).getReturnType()}
+	 *   がプリミティブ型を表現する場合、ハンドラのメソッドはそのラッパ型の値を返す必要がある。
+	 *   </li>
+	 *   <li>
+	 *   {@link CtMethod#getReturnType() ((CtMethod) behavior).getReturnType()}
+	 *   がオブジェクト型を表現する場合、ハンドラのメソッドはその型、またはそのサブタイプの値を返す必要がある。
+	 *   </li>
+	 *   </ul>
+	 * </li>
+	 * <li> インスタンス生成に対するハンドラ
+	 *   <ul>
+	 *   <li> {@code self}が表現する型、またはそのサブタイプの値を返す必要がある。 </li>
+	 *   </ul>
+	 * </li>
+	 * </ul>
 	 * @param self このメソッドまたはコンストラクタを公開するクラス
 	 * @param behavior 検査対象のメソッドまたはコンストラクタ
 	 * @return ジョインポイントとして利用する場合は{@code true}、そうでない場合は{@code false}

Added: leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/AopAllianceDriver.java
===================================================================
--- leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/AopAllianceDriver.java	                        (rev 0)
+++ leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/AopAllianceDriver.java	2009-10-07 18:49:11 UTC (rev 3729)
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2007-2009 Jiemamy Project and the Others.
+ * Created on 2009/10/08
+ *
+ * This file is part of Jiemamy.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.jiemamy.utils.enhancer.driver;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+import org.aopalliance.intercept.ConstructorInterceptor;
+import org.aopalliance.intercept.ConstructorInvocation;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+import org.jiemamy.utils.enhancer.Invocation;
+import org.jiemamy.utils.enhancer.InvocationHandler;
+
+/**
+ * TODO for Suguru ARAKAWA
+ * 
+ * @version 0.2.0
+ * @since 0.2.0
+ * @version $Id$
+ * @author Suguru ARAKAWA
+ */
+public class AopAllianceDriver {
+	
+	/**
+	 * TODO for Suguru ARAKAWA
+	 * 
+	 * @param interceptor
+	 * @return
+	 * @throws NullPointerException 引数に{@code null}が指定された場合
+	 */
+	public static InvocationHandler toHandler(MethodInterceptor interceptor) {
+		if (interceptor == null) {
+			throw new NullPointerException("interceptor is null"); //$NON-NLS-1$
+		}
+		return new MethodInterceptorDriver(interceptor);
+	}
+	
+	/**
+	 * TODO for Suguru ARAKAWA
+	 * 
+	 * @param interceptor
+	 * @return
+	 * @throws NullPointerException 引数に{@code null}が指定された場合
+	 */
+	public static InvocationHandler toHandler(ConstructorInterceptor interceptor) {
+		if (interceptor == null) {
+			throw new IllegalArgumentException("interceptor is null"); //$NON-NLS-1$
+		}
+		return new ConstructorInterceptorDriver(interceptor);
+	}
+	
+	static Object doProceed(Invocation invocation) throws Throwable {
+		try {
+			return invocation.proceed();
+		} catch (InvocationTargetException e) {
+			throw e.getTargetException();
+		}
+	}
+	
+
+	/**
+	 * TODO for Suguru ARAKAWA
+	 * 
+	 * @version 0.2.0
+	 * @since 0.2.0
+	 * @version $Id$
+	 * @author Suguru ARAKAWA
+	 */
+	public static class MethodInterceptorDriver implements InvocationHandler {
+		
+		private MethodInterceptor interceptor;
+		
+
+		/**
+		 * インスタンスを生成する。
+		 * 
+		 * @param interceptor ラップする {@link MethodInterceptor}
+		 * @throws NullPointerException 引数に{@code null}が指定された場合
+		 */
+		public MethodInterceptorDriver(MethodInterceptor interceptor) {
+			if (interceptor == null) {
+				throw new NullPointerException("interceptor is null"); //$NON-NLS-1$
+			}
+			this.interceptor = interceptor;
+		}
+		
+		public Object handle(Invocation invocation) throws Throwable {
+			if ((invocation.getTarget() instanceof Method) == false) {
+				return doProceed(invocation);
+			}
+			return interceptor.invoke(new MethodInvocationDriver(invocation));
+		}
+	}
+	
+	/**
+	 * 
+	 * TODO for Suguru ARAKAWA
+	 * 
+	 * @version 0.2.0
+	 * @since 0.2.0
+	 * @version $Id$
+	 * @author Suguru ARAKAWA
+	 */
+	public static class ConstructorInterceptorDriver implements InvocationHandler {
+		
+		private ConstructorInterceptor interceptor;
+		
+
+		/**
+		 * インスタンスを生成する。
+		 * 
+		 * @param interceptor ラップする {@link ConstructorInterceptor}
+		 * @throws NullPointerException 引数に{@code null}が指定された場合
+		 */
+		public ConstructorInterceptorDriver(ConstructorInterceptor interceptor) {
+			if (interceptor == null) {
+				throw new NullPointerException("interceptor is null"); //$NON-NLS-1$
+			}
+			this.interceptor = interceptor;
+		}
+		
+		public Object handle(Invocation invocation) throws Throwable {
+			if ((invocation.getTarget() instanceof Constructor<?>) == false) {
+				return doProceed(invocation);
+			}
+			return interceptor.construct(new ConstructorInvocationDriver(invocation));
+		}
+	}
+	
+	private static class MethodInvocationDriver implements MethodInvocation {
+		
+		private Invocation invocation;
+		
+		private Method executable;
+		
+
+		/**
+		 * インスタンスを生成する。
+		 * @param invocation 呼び出しを表現するオブジェクト
+		 */
+		public MethodInvocationDriver(Invocation invocation) {
+			assert invocation != null;
+			this.invocation = invocation;
+			
+			Member target = invocation.getTarget();
+			assert target instanceof Method;
+			executable = (Method) target;
+		}
+		
+		public Method getMethod() {
+			return executable;
+		}
+		
+		public Object[] getArguments() {
+			return invocation.getArguments();
+		}
+		
+		public AccessibleObject getStaticPart() {
+			return executable;
+		}
+		
+		public Object getThis() {
+			return invocation.getInvoker();
+		}
+		
+		public Object proceed() throws Throwable {
+			return doProceed(invocation);
+		}
+	}
+	
+	private static class ConstructorInvocationDriver implements ConstructorInvocation {
+		
+		private Invocation invocation;
+		
+		private Constructor<?> executable;
+		
+
+		/**
+		 * インスタンスを生成する。
+		 * @param invocation 呼び出しを表現するオブジェクト
+		 */
+		public ConstructorInvocationDriver(Invocation invocation) {
+			assert invocation != null;
+			this.invocation = invocation;
+			
+			Member target = invocation.getTarget();
+			assert target instanceof Constructor<?>;
+			executable = (Constructor<?>) target;
+		}
+		
+		public Constructor<?> getConstructor() {
+			return executable;
+		}
+		
+		public Object[] getArguments() {
+			return invocation.getArguments();
+		}
+		
+		public AccessibleObject getStaticPart() {
+			return executable;
+		}
+		
+		public Object getThis() {
+			return invocation.getInvoker();
+		}
+		
+		public Object proceed() throws Throwable {
+			return doProceed(invocation);
+		}
+	}
+}


Property changes on: leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/AopAllianceDriver.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Author Id Revision HeadURL
Added: svn:eol-style
   + native

Added: leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/ProxyDriver.java
===================================================================
--- leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/ProxyDriver.java	                        (rev 0)
+++ leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/ProxyDriver.java	2009-10-07 18:49:11 UTC (rev 3729)
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2009 the Seasar Foundation and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.jiemamy.utils.enhancer.driver;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Proxy;
+
+import javassist.CtBehavior;
+import javassist.CtClass;
+import javassist.CtConstructor;
+
+import org.jiemamy.utils.enhancer.Enhance;
+import org.jiemamy.utils.enhancer.Invocation;
+import org.jiemamy.utils.enhancer.InvocationHandler;
+import org.jiemamy.utils.enhancer.InvocationPointcut;
+
+/**
+ * {@link java.lang.reflect.Proxy}のインスタンスを生成するための{@link Enhance}を作成する。
+ * @version $Date$
+ * @author Suguru ARAKAWA
+ */
+public class ProxyDriver {
+	
+	/**
+	 * 指定のインターフェースが表すインターフェースプロダクトを作成する際に、
+	 * {@link java.lang.reflect.Proxy}を利用してプロダクトインスタンスの代わりに
+	 * Proxyを返すためのエンハンスを作成する。
+	 * @param anInterface Proxyを作成する対象のインターフェース
+	 * @param handler 指定のインターフェースに対するメソッド呼び出しをハンドルするハンドラ
+	 *     これはfactory-enhancerの{@link InvocationHandler}ではなく、
+	 *     標準の{@link java.lang.reflect.InvocationHandler}である
+	 * @return 指定のインターフェースのメソッドを指定のハンドラでフックするProxyを生成するエンハンス
+	 * @throws IllegalArgumentException 引数{@code anInterface}がProxyを作成できない型である場合
+	 * @throws NullPointerException 引数に{@code null}が指定された場合
+	 */
+	public static Enhance newEnhance(Class<?> anInterface, java.lang.reflect.InvocationHandler handler) {
+		if (anInterface == null) {
+			throw new NullPointerException("anInterface is null"); //$NON-NLS-1$
+		}
+		if (handler == null) {
+			throw new NullPointerException("handler is null"); //$NON-NLS-1$
+		}
+		
+		// Proxyクラスを作って、それをインスタンス化するコンストラクタを取り出す
+		Class<?> proxyClass = Proxy.getProxyClass(anInterface.getClassLoader(), anInterface);
+		Constructor<?> constructor;
+		try {
+			constructor = proxyClass.getConstructor(java.lang.reflect.InvocationHandler.class);
+		} catch (NoSuchMethodException e) {
+			throw new AssertionError(e);
+		}
+		return new Enhance(
+				new ProxyPointcut(anInterface.getName()),
+				new ProxyHandler(constructor, handler));
+	}
+	
+	/**
+	 * インスタンス生成の禁止。
+	 */
+	private ProxyDriver() {
+		throw new AssertionError();
+	}
+	
+
+	/**
+	 * プロクシ作成の対象となるインターフェースプロダクト生成へのポイントカット。
+	 * @version $Date$
+	 * @author Suguru ARAKAWA
+	 */
+	private static class ProxyPointcut implements InvocationPointcut {
+		
+		/**
+		 * Proxyインスタンス生成の対象とするインターフェースの名前
+		 */
+		private String targetName;
+		
+
+		/**
+		 * インスタンスを生成する。
+		 * @param targetName 対象インターフェースの名称
+		 * @throws NullPointerException 引数に{@code null}が指定された場合
+		 */
+		public ProxyPointcut(String targetName) {
+			if (targetName == null) {
+				throw new NullPointerException("targetName is null"); //$NON-NLS-1$
+			}
+			this.targetName = targetName;
+		}
+		
+		public boolean isTarget(CtClass self, CtBehavior behavior) {
+			// インスタンス生成のみ
+			if ((behavior instanceof CtConstructor) == false) {
+				return false;
+			}
+			
+			// 対象インターフェースのみ
+			if (self.getName().equals(targetName) == false) {
+				return false;
+			}
+			return true;
+		}
+	}
+	
+	private static class ProxyHandler implements InvocationHandler {
+		
+		/**
+		 * Proxyインスタンスを生成するためのコンストラクタ。
+		 */
+		private Constructor<?> proxyCreator;
+		
+		/**
+		 * Proxyインスタンスに渡す{@code java.lang.reflect.InvocationHandler}。
+		 */
+		private java.lang.reflect.InvocationHandler handler;
+		
+
+		/**
+		 * インスタンスを生成する。
+		 * @param proxyCreator 該当Proxyのインスタンスを生成するコンストラクタ
+		 * @param handler 該当Proxyの各メソッド呼び出しに対するハンドラ
+		 * @throws NullPointerException 引数に{@code null}が指定された場合
+		 */
+		public ProxyHandler(
+				Constructor<?> proxyCreator,
+				java.lang.reflect.InvocationHandler handler) {
+			if (proxyCreator == null) {
+				throw new NullPointerException("proxyCreator is null"); //$NON-NLS-1$
+			}
+			if (handler == null) {
+				throw new NullPointerException("handler is null"); //$NON-NLS-1$
+			}
+			this.proxyCreator = proxyCreator;
+			this.handler = handler;
+		}
+		
+		/**
+		 * この実装では{@code invocation.proceed()}を実行せずに、
+		 * 代わりにProxyインスタンスを生成して返す。
+		 */
+		public Object handle(Invocation invocation) throws Throwable {
+			// ハンドラインスタンスを共有しない方法も考えたい
+			return proxyCreator.newInstance(new Object[] {
+				handler
+			});
+		}
+	}
+}


Property changes on: leto/factory-enhancer/branches/interface-enhancer/src/main/java/org/jiemamy/utils/enhancer/driver/ProxyDriver.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Author Id Revision HeadURL
Added: svn:eol-style
   + native

Modified: leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/Main.java
===================================================================
--- leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/Main.java	2009-10-07 18:16:38 UTC (rev 3728)
+++ leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/Main.java	2009-10-07 18:49:11 UTC (rev 3729)
@@ -23,6 +23,7 @@
 import org.jiemamy.utils.enhancer.Enhance;
 import org.jiemamy.utils.enhancer.Enhancer;
 import org.jiemamy.utils.enhancer.InterfaceEnhancer;
+import org.jiemamy.utils.enhancer.driver.ProxyDriver;
 
 /**
  * このパッケージのプログラムエントリ。
@@ -67,8 +68,8 @@
         Callable<String> callable = factory.newCallable();
 
         System.out.println("プロダクトはいずれもProxyになってるはず");
-        System.out.printf("runnable is proxy = %s%n", Proxy.isProxyClass(runnable.getClass()));
-        System.out.printf("callable is proxy = %s%n", Proxy.isProxyClass(callable.getClass()));
+        System.out.printf("runnable.getClass() is proxy = %s%n", Proxy.isProxyClass(runnable.getClass()));
+        System.out.printf("callable.getClass() is proxy = %s%n", Proxy.isProxyClass(callable.getClass()));
 
         System.out.println("run()メソッドの呼び出し");
         runnable.run();

Deleted: leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ProxyDriver.java
===================================================================
--- leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ProxyDriver.java	2009-10-07 18:16:38 UTC (rev 3728)
+++ leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ProxyDriver.java	2009-10-07 18:49:11 UTC (rev 3729)
@@ -1,156 +0,0 @@
-/*
- * Copyright 2009 the Seasar Foundation and the Others.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-package org.jiemamy.util.enhancer.example._10proxy;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Proxy;
-
-import javassist.CtBehavior;
-import javassist.CtClass;
-import javassist.CtConstructor;
-
-import org.jiemamy.utils.enhancer.Enhance;
-import org.jiemamy.utils.enhancer.Invocation;
-import org.jiemamy.utils.enhancer.InvocationHandler;
-import org.jiemamy.utils.enhancer.InvocationPointcut;
-
-/**
- * {@link java.lang.reflect.Proxy}のインスタンスを生成するための{@link Enhance}を作成する。
- * @version $Date$
- * @author Suguru ARAKAWA
- */
-public class ProxyDriver {
-
-    /**
-     * 指定のインターフェースが表すインターフェースプロダクトを作成する際に、
-     * {@link java.lang.reflect.Proxy}を利用してプロダクトインスタンスの代わりに
-     * Proxyを返すためのエンハンスを作成する。
-     * @param anInterface Proxyを作成する対象のインターフェース
-     * @param handler 指定のインターフェースに対するメソッド呼び出しをハンドルするハンドラ
-     *     これはfactory-enhancerの{@link InvocationHandler}ではなく、
-     *     標準の{@link java.lang.reflect.InvocationHandler}である
-     * @return 指定のインターフェースのメソッドを指定のハンドラでフックするProxyを生成するエンハンス
-     * @throws IllegalArgumentException 引数{@code anInterface}がProxyを作成できない型である場合
-     * @throws NullPointerException 引数に{@code null}が指定された場合
-     */
-    public static Enhance newEnhance(Class<?> anInterface, java.lang.reflect.InvocationHandler handler) {
-        if (anInterface == null) {
-            throw new NullPointerException("anInterface is null"); //$NON-NLS-1$
-        }
-        if (handler == null) {
-            throw new NullPointerException("handler is null"); //$NON-NLS-1$
-        }
-
-        // Proxyクラスを作って、それをインスタンス化するコンストラクタを取り出す
-        Class<?> proxyClass = Proxy.getProxyClass(anInterface.getClassLoader(), anInterface);
-        Constructor<?> constructor;
-        try {
-            constructor = proxyClass.getConstructor(java.lang.reflect.InvocationHandler.class);
-        }
-        catch (NoSuchMethodException e) {
-            throw new AssertionError(e);
-        }
-        return new Enhance(
-            new ProxyPointcut(anInterface.getName()),
-            new ProxyHandler(constructor, handler));
-    }
-
-    /**
-     * インスタンス生成の禁止。
-     */
-    private ProxyDriver() {
-        throw new AssertionError();
-    }
-
-    /**
-     * プロクシ作成の対象となるインターフェースプロダクト生成へのポイントカット。
-     * @version $Date$
-     * @author Suguru ARAKAWA
-     */
-    private static class ProxyPointcut implements InvocationPointcut {
-
-        /**
-         * Proxyインスタンス生成の対象とするインターフェースの名前
-         */
-        private String targetName;
-
-        /**
-         * インスタンスを生成する。
-         * @param targetName 対象インターフェースの名称
-         * @throws NullPointerException 引数に{@code null}が指定された場合
-         */
-        public ProxyPointcut(String targetName) {
-            if (targetName == null) {
-                throw new NullPointerException("targetName is null"); //$NON-NLS-1$
-            }
-            this.targetName = targetName;
-        }
-
-        public boolean isTarget(CtClass self, CtBehavior behavior) {
-            // インスタンス生成のみ
-            if ((behavior instanceof CtConstructor) == false) {
-                return false;
-            }
-
-            // 対象インターフェースのみ
-            if (self.getName().equals(targetName) == false) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    private static class ProxyHandler implements InvocationHandler {
-
-        /**
-         * Proxyインスタンスを生成するためのコンストラクタ。
-         */
-        private Constructor<?> proxyCreator;
-
-        /**
-         * Proxyインスタンスに渡す{@code java.lang.reflect.InvocationHandler}。
-         */
-        private java.lang.reflect.InvocationHandler handler;
-
-        /**
-         * インスタンスを生成する。
-         * @param proxyCreator 該当Proxyのインスタンスを生成するコンストラクタ
-         * @param handler 該当Proxyの各メソッド呼び出しに対するハンドラ
-         * @throws NullPointerException 引数に{@code null}が指定された場合
-         */
-        public ProxyHandler(
-                Constructor<?> proxyCreator,
-                java.lang.reflect.InvocationHandler handler) {
-            if (proxyCreator == null) {
-                throw new NullPointerException("proxyCreator is null"); //$NON-NLS-1$
-            }
-            if (handler == null) {
-                throw new NullPointerException("handler is null"); //$NON-NLS-1$
-            }
-            this.proxyCreator = proxyCreator;
-            this.handler = handler;
-        }
-
-        /**
-         * この実装では{@code invocation.proceed()}を実行せずに、
-         * 代わりにProxyインスタンスを生成して返す。
-         */
-        public Object handle(Invocation invocation) throws Throwable {
-            // ハンドラインスタンスを共有しない方法も考えたい
-            return proxyCreator.newInstance(new Object[] { handler });
-        }
-    }
-}




Jiemamy-notify メーリングリストの案内
Back to archive index