svnno****@sourc*****
svnno****@sourc*****
2009年 10月 5日 (月) 09:53:40 JST
Revision: 3701 http://sourceforge.jp/projects/jiemamy/svn/view?view=rev&revision=3701 Author: ashigeru Date: 2009-10-05 09:53:40 +0900 (Mon, 05 Oct 2009) Log Message: ----------- ロギングとテストを少し整備 Modified Paths: -------------- leto/factory-enhancer/branches/interface-enhancer-20091004/src/main/java/org/jiemamy/utils/enhancer/InterfaceEnhancer.java leto/factory-enhancer/branches/interface-enhancer-20091004/src/main/java/org/jiemamy/utils/enhancer/helper/EnhanceManipulator.java leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/InterfaceEnhancerTest.java leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/InterfaceProduct.java Added Paths: ----------- leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/ConcreteProduct.java Modified: leto/factory-enhancer/branches/interface-enhancer-20091004/src/main/java/org/jiemamy/utils/enhancer/InterfaceEnhancer.java =================================================================== --- leto/factory-enhancer/branches/interface-enhancer-20091004/src/main/java/org/jiemamy/utils/enhancer/InterfaceEnhancer.java 2009-10-04 12:10:13 UTC (rev 3700) +++ leto/factory-enhancer/branches/interface-enhancer-20091004/src/main/java/org/jiemamy/utils/enhancer/InterfaceEnhancer.java 2009-10-05 00:53:40 UTC (rev 3701) @@ -124,61 +124,6 @@ * <li> {@code productSuperClass}は(列挙でない)クラス型を表現する </li> * <li> {@code productSuperClass}は引数をとらないコンストラクタを提供する </li> * </ul> - * <p> - * また、このクラスによって実装される対象は、つぎのそれぞれの条件をすべて満たすもののみである。 - * </p> - * <ul> - * <li> 拡張されるインスタンス生成式 <ul> - * <li> - * {@code factoryImplementation}に直接記述されたクラスインスタンス生成式である - * </li> - * <li> 対象のクラスが{@code public}で宣言されている </li> - * <li> 実行するコンストラクタが{@code public}で宣言されている </li> - * <li> - * 実行するコンストラクタが{@code enhanceList}に含まれるいずれかの拡張対象となる - * </li> </ul> - * </li> - * <li> 拡張されるプロダクトクラス <ul> - * <li> 下記のすべてを満たすいずれかのインスタンス生成式の対象にとるクラスである : <ul> - * <li> - * {@code factoryImplementation}に直接記述されたインスタンス生成式である - * </li> - * <li> 対象のクラスが{@code public}で宣言されている </li> - * <li> 対象のクラスが{@code final}で宣言されて<b>いない</b> </li> - * <li> 実行対象のコンストラクタが{@code public}で宣言されている </li> </ul> - * </li> - * <li> クラスが公開するいずれかのメソッドが次の条件をすべて満たす - * (つまり、このクラスが拡張されるプロダクトメソッドを含む): <ul> - * <li> {@code public}で宣言されている </li> - * <li> {@code final}で宣言されて<b>いない</b> </li> - * <li> {@code static}で宣言されて<b>いない</b> </li> - * <li> - * {@code enhanceList}に含まれるいずれかの拡張対象となる - * </li> </ul> - * </li> </ul> - * </li> - * <li> 拡張されるプロダクトメソッド <ul> - * <li> - * 上記"拡張されるプロダクトクラス"の対象となったクラスが公開するメソッドである - * (継承したメソッドを含む) - * </li> - * <li> {@code public}で宣言されている </li> - * <li> {@code final}で宣言されて<b>いない</b> </li> - * <li> {@code static}で宣言されて<b>いない</b> </li> - * <li> ブリッジメソッドでない </li> - * <li> コンパイラによって合成された({@code synthetic})メソッドでない </li> - * <li> - * {@code enhanceList}に含まれるいずれかの拡張対象となる - * </li> </ul> - * </li> - * </ul> - * <p> - * なお、プロダクトクラスが拡張される場合、このオブジェクトが作成するファクトリは - * 拡張されたプロダクトクラスをインスタンス化して返す。 - * ただし、拡張対象となるプロダクトクラスのうち、{@code public}でない - * コンストラクタを起動するようなインスタンス生成式は拡張されていない通常のプロダクトクラスの - * インスタンスを生成する。 - * </p> * @param factoryInterface 実装を生成する対象のファクトリインターフェース * @param productSuperClass それぞれのプロダクトが実装する親クラス * @param enhanceList 拡張を定義するオブジェクトの一覧 Modified: leto/factory-enhancer/branches/interface-enhancer-20091004/src/main/java/org/jiemamy/utils/enhancer/helper/EnhanceManipulator.java =================================================================== --- leto/factory-enhancer/branches/interface-enhancer-20091004/src/main/java/org/jiemamy/utils/enhancer/helper/EnhanceManipulator.java 2009-10-04 12:10:13 UTC (rev 3700) +++ leto/factory-enhancer/branches/interface-enhancer-20091004/src/main/java/org/jiemamy/utils/enhancer/helper/EnhanceManipulator.java 2009-10-05 00:53:40 UTC (rev 3701) @@ -342,97 +342,6 @@ return implementation; } - /* - // 未検証だが、binary compatibilityの関係で、インターフェースメソッドが実装されていなくても問題なく動きそう - private static void createImplementationMethodStubs( - CtClass implementation, - CtClass baseInterface) throws EnhanceException { - assert implementation != null; - assert baseInterface != null; - LOG.trace("Creating implementation method stubs: {} -> {}", - implementation.getName(), baseInterface.getName()); - - Set<NameAndDescriptor> methods = collectInterfaceMethods(baseInterface); - for (NameAndDescriptor identity : methods) { - CtMethod method = getMethod(implementation, identity); - - // オーバーライドできないメソッドはスキップ - if (method != null && canOverride(method) == false) { - LOG.debug("A implemented method {}{} is final, so point cut is not created.", - method.getName(), method.getSignature()); - continue; - } - - // オーバーライドしてデリゲートか、未実装例外をスローするかどちらかのメソッドを追加 - addImplementationMethod(implementation, identity.method, method != null); - } - } - - private static boolean canOverride(CtMethod method) { - assert method != null; - int modifiers = method.getModifiers(); - return Modifier.isFinal(modifiers) == false - && Modifier.isStatic(modifiers) == false; - } - - private static void addImplementationMethod( - CtClass implementation, - CtMethod interfaceMethod, - boolean delegateSuper) throws EnhanceException { - assert implementation != null; - assert interfaceMethod != null; - assert isStatic(interfaceMethod) == false; - - LOG.trace("Implementing method: {}", interfaceMethod.getName()); - - CtMethod stub; - try { - stub = new CtMethod( - interfaceMethod.getReturnType(), - interfaceMethod.getName(), - interfaceMethod.getParameterTypes(), - implementation); - } catch (NotFoundException e) { - throw new EnhanceException( - MessageFormat.format( - "Cannot create stub method for {0} to {1}", - interfaceMethod, - implementation.getName()), - e); - } - stub.setModifiers(Modifier.PUBLIC); - try { - if (delegateSuper) { - // 親クラスのメソッドを呼び出し - if (isVoid(interfaceMethod)) { - stub.setBody(String.format( - "super.%s($$);", - interfaceMethod.getName())); - } else { - stub.setBody(String.format( - "return super.%s($$);", - interfaceMethod.getName())); - } - } else { - // 親クラスのメソッドがないので、AbstractMethodErrorをスローしておく - stub.setBody(String.format( - "throw new java.lang.AbstractMethodError(\"%s\");", - interfaceMethod.getName())); - } - } catch (CannotCompileException e) { - e.printStackTrace(); - } - } - - private static CtMethod getMethod(CtClass aClass, NameAndDescriptor method) { - try { - return aClass.getMethod(method.name, method.descriptor); - } catch (NotFoundException e) { - return null; - } - } - */ - private static Set<NameAndDescriptor> collectInterfaceMethods(CtClass anInterface) throws EnhanceException { assert anInterface != null; assert anInterface.isInterface(); @@ -598,12 +507,24 @@ method.getSignature() }); bypass.setModifiers(Modifier.PUBLIC); - if (method.getDeclaringClass().isInterface()) { + if (isDeclaredInClass(method, enhance.getSuperclass()) == false) { + LOG.debug("Bypass target {}{} is not declared in {}; this throws AbstractMethodError", new Object[] { + method.getName(), + method.getSignature(), + enhance.getSuperclass().getName() + }); bypass.setBody(String.format("throw new java.lang.AbstractMethodError(\"%s\");", method.getName())); - } else if (isVoid(method)) { - bypass.setBody(String.format("super.%s($$);", method.getName())); } else { - bypass.setBody(String.format("return super.%s($$);", method.getName())); + LOG.debug("Bypass target {}{} is in {}; this just invokes it", new Object[] { + method.getName(), + method.getSignature(), + enhance.getSuperclass().getName() + }); + if (isVoid(method)) { + bypass.setBody(String.format("super.%s($$);", method.getName())); + } else { + bypass.setBody(String.format("return super.%s($$);", method.getName())); + } } enhance.addMethod(bypass); return bypass; @@ -616,6 +537,25 @@ } } + /** + * 指定のメソッドが指定のクラスで実際に宣言されている場合のみ{@code true}を返す。 + * @param method 対象のメソッド + * @param aClass 対象のクラス + * @return 実際に宣言されている場合に{@code true} + */ + private static boolean isDeclaredInClass(CtMethod method, CtClass aClass) { + assert method != null; + if (aClass == null) { + return false; + } + try { + aClass.getMethod(method.getName(), method.getSignature()); + return true; + } catch (NotFoundException e) { + return false; + } + } + private static boolean isVoid(CtMethod method) { assert method != null; try { Added: leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/ConcreteProduct.java =================================================================== --- leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/ConcreteProduct.java (rev 0) +++ leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/ConcreteProduct.java 2009-10-05 00:53:40 UTC (rev 3701) @@ -0,0 +1,34 @@ +/* + * Copyright 2007-2009 Jiemamy Project and the Others. + * Created on 2009/10/04 + * + * 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; + +/** + * 単純なプロダクト。 + * @version $Id: InterfaceProduct.java 3699 2009-10-04 11:33:48Z ashigeru $ + * @author Suguru ARAKAWA + */ +public class ConcreteProduct { + + /** + * @return {@code "Concrete"} + */ + public String getMessage() { + return "Concrete"; + } +} Property changes on: leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/ConcreteProduct.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/InterfaceEnhancerTest.java =================================================================== --- leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/InterfaceEnhancerTest.java 2009-10-04 12:10:13 UTC (rev 3700) +++ leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/InterfaceEnhancerTest.java 2009-10-05 00:53:40 UTC (rev 3701) @@ -29,6 +29,7 @@ import org.junit.Test; import org.jiemamy.utils.enhancer.aspect.StringResultPointcut; +import org.jiemamy.utils.enhancer.aspect.ThroughHandler; /** * Test for {@link InterfaceEnhancer}. @@ -90,6 +91,23 @@ assertThat(product.toString(), is("Hello")); } + /** + * Test method for {@link org.jiemamy.utils.enhancer.AbstractEnhancer#getFactory()}. + * @throws Exception if occur + */ + @Test + public void testGetFactory_Through() throws Exception { + Enhance enhance = new Enhance(new StringResultPointcut(), new ThroughHandler()); + InterfaceEnhancer<SimpleInterfaceFactory> enhancer = new InterfaceEnhancer<SimpleInterfaceFactory>( + SimpleInterfaceFactory.class, + ConcreteProduct.class, + enhances(enhance)); + Factory<? extends SimpleInterfaceFactory> metaFactory = enhancer.getFactory(); + SimpleInterfaceFactory factory = metaFactory.newInstance(); + InterfaceProduct product = factory.newProduct(); + assertThat(product.getMessage(), is("Concrete")); + } + private static List<Enhance> enhances(Enhance... enhances) { return Arrays.asList(enhances); } Modified: leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/InterfaceProduct.java =================================================================== --- leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/InterfaceProduct.java 2009-10-04 12:10:13 UTC (rev 3700) +++ leto/factory-enhancer/branches/interface-enhancer-20091004/src/test/java/org/jiemamy/utils/enhancer/InterfaceProduct.java 2009-10-05 00:53:40 UTC (rev 3701) @@ -20,7 +20,6 @@ /** * 単純なプロダクト。 - * @since 0.3 * @version $Id$ * @author Suguru ARAKAWA */