001// Copyright 2011 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.internal.plastic; 016 017import java.lang.annotation.Annotation; 018import java.lang.reflect.Method; 019 020import org.apache.tapestry5.plastic.InstanceContext; 021import org.apache.tapestry5.plastic.MethodInvocation; 022 023public abstract class AbstractMethodInvocation implements MethodInvocation 024{ 025 private final Object instance; 026 027 private final InstanceContext instanceContext; 028 029 private final MethodInvocationBundle bundle; 030 031 private int adviceIndex; 032 033 protected AbstractMethodInvocation(Object instance, InstanceContext instanceContext, MethodInvocationBundle bundle) 034 { 035 this.instance = instance; 036 this.instanceContext = instanceContext; 037 this.bundle = bundle; 038 } 039 040 private Exception checkedException; 041 042 /** 043 * Invoked from the implementation of {@link MethodInvocation#setReturnValue(Object)}. 044 */ 045 protected void clearCheckedException() 046 { 047 checkedException = null; 048 } 049 050 @Override 051 public void rethrow() 052 { 053 if (checkedException != null) 054 throw new RuntimeException(checkedException); 055 } 056 057 @Override 058 public boolean didThrowCheckedException() 059 { 060 return checkedException != null; 061 } 062 063 @Override 064 public <T extends Throwable> T getCheckedException(Class<T> exceptionType) 065 { 066 assert exceptionType != null; 067 068 if (exceptionType.isInstance(checkedException)) 069 return exceptionType.cast(checkedException); 070 071 return null; 072 } 073 074 @Override 075 public Object getInstance() 076 { 077 return instance; 078 } 079 080 @Override 081 public InstanceContext getInstanceContext() 082 { 083 return instanceContext; 084 } 085 086 @Override 087 public MethodInvocation proceed() 088 { 089 if (adviceIndex == bundle.advice.length) 090 proceedToAdvisedMethod(); 091 else 092 bundle.advice[adviceIndex++].advise(this); 093 094 return this; 095 } 096 097 @Override 098 public MethodInvocation setCheckedException(Exception exception) 099 { 100 checkedException = exception; 101 102 return this; 103 } 104 105 @Override 106 public <T extends Annotation> boolean hasAnnotation(Class<T> annotationType) 107 { 108 return getAnnotation(annotationType) != null; 109 } 110 111 @Override 112 public <T extends Annotation> T getAnnotation(Class<T> annotationType) 113 { 114 return getMethod().getAnnotation(annotationType); 115 } 116 117 @Override 118 public Method getMethod() 119 { 120 return bundle.getMethod(getInstance()); 121 } 122 123 /** This is implemented in a runtime-generated subclass. */ 124 protected abstract void proceedToAdvisedMethod(); 125}