[Jiemamy-notify:2785] commit [3709] Proxyを生成するサンプルを追加。ただしまだ動かない。

アーカイブの一覧に戻る

svnno****@sourc***** svnno****@sourc*****
2009年 10月 6日 (火) 09:53:46 JST


Revision: 3709
          http://sourceforge.jp/projects/jiemamy/svn/view?view=rev&revision=3709
Author:   ashigeru
Date:     2009-10-06 09:53:46 +0900 (Tue, 06 Oct 2009)

Log Message:
-----------
Proxyを生成するサンプルを追加。ただしまだ動かない。

Added Paths:
-----------
    leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/
    leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ExecutableFactory.java
    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/ProxyDriver.java

Added: leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ExecutableFactory.java
===================================================================
--- leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ExecutableFactory.java	                        (rev 0)
+++ leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ExecutableFactory.java	2009-10-06 00:53:46 UTC (rev 3709)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009 Jiemamy Project 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.util.concurrent.Callable;
+
+/**
+ * {@link Runnable}と{@link Callable}を生成するファクトリ。
+ * @version $Date: 2009-10-05 20:36:43 +0900 (月, 05 10 2009) $
+ * @author Suguru ARAKAWA (Gluegent, Inc.)
+ */
+public interface ExecutableFactory {
+
+    /**
+     * @return a runnable
+     */
+    Runnable newRunnable();
+
+    /**
+     * @return a callable
+     */
+    Callable<String> newCallable();
+}


Property changes on: leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ExecutableFactory.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: 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	                        (rev 0)
+++ leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/Main.java	2009-10-06 00:53:46 UTC (rev 3709)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2009 Jiemamy Project 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.Method;
+import java.util.Arrays;
+import java.util.Properties;
+
+import org.jiemamy.utils.enhancer.Enhance;
+import org.jiemamy.utils.enhancer.Enhancer;
+import org.jiemamy.utils.enhancer.InterfaceEnhancer;
+
+/**
+ * このパッケージのプログラムエントリ。
+ * @version $Date: 2009-10-05 20:36:43 +0900 (月, 05 10 2009) $
+ * @author Suguru ARAKAWA (Gluegent, Inc.)
+ */
+public class Main {
+
+    /**
+     * プログラムエントリ。
+     * @param args 無視される
+     * @throws Exception うまくいかない場合
+     */
+    public static void main(String...args) throws Exception {
+        Enhancer<ExecutableFactory> enhancer = new InterfaceEnhancer<ExecutableFactory>(
+                ExecutableFactory.class,
+                Properties.class, // Propertiesを実装するようにする
+                Arrays.<Enhance>asList(
+                    // Daoの実装を生成する際に、 DaoFactory.newInstanceの引数でうまい具合に初期化
+                    ProxyDriver.newEnhane(Runnable.class, new java.lang.reflect.InvocationHandler() {
+                        public Object invoke(Object proxy, Method method, Object[] a) {
+                            System.out.printf("Hook %s%n", method);
+                            return null;
+                        }
+                    })
+                )
+        );
+        System.out.println("ファクトリを生成");
+        ExecutableFactory factory = enhancer.getFactory().newInstance();
+
+        System.out.println("プロダクトを生成");
+        Runnable runnable = factory.newRunnable();
+
+        System.out.println("run()メソッドの呼び出し");
+        runnable.run();
+    }
+}


Property changes on: leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/Main.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: 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	                        (rev 0)
+++ leto/factory-enhancer-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ProxyDriver.java	2009-10-06 00:53:46 UTC (rev 3709)
@@ -0,0 +1,154 @@
+/*
+ * 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 指定のインターフェースに対するメソッド呼び出しをハンドルするハンドラ
+     * @return 指定のインターフェースのメソッドを指定のハンドラでフックするProxyを生成するエンハンス
+     * @throws IllegalArgumentException 引数{@code anInterface}がプロクシを作成できないクラスである場合
+     * @throws NullPointerException 引数に{@code null}が指定された場合
+     */
+    public static Enhance newEnhane(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
+         * @param handler
+         * @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-example/branches/interface-enhancer/src/main/java/org/jiemamy/util/enhancer/example/_10proxy/ProxyDriver.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain




Jiemamy-notify メーリングリストの案内
アーカイブの一覧に戻る