// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package jodd.proxetta.pointcuts;
import jodd.asm.AsmUtil;
import jodd.proxetta.ProxyPointcut;
import jodd.proxetta.MethodInfo;
import jodd.proxetta.AnnotationInfo;
import jodd.proxetta.ClassInfo;
import jodd.proxetta.asm.ProxettaAsmUtil;
import jodd.util.Wildcard;
import java.lang.annotation.Annotation;
/**
* {@link jodd.proxetta.ProxyPointcut} support methods.
*/
public abstract class ProxyPointcutSupport implements ProxyPointcut {
/**
* Returns <code>true</code> if method is public.
*/
public boolean isPublic(MethodInfo methodInfo) {
return (methodInfo.getAccessFlags() & AsmUtil.ACC_PUBLIC) != 0;
}
/**
* Returns <code>true</code> if method is annotated with provided annotation.
*/
public AnnotationInfo getAnnotation(MethodInfo methodInfo, Class<? extends Annotation> mi) {
AnnotationInfo[] anns = methodInfo.getAnnotations();
if (anns == null) {
return null;
}
String anName = mi.getName();
for (AnnotationInfo ann : anns) {
if (ann.getAnnotationClassname().equals(anName)) {
return ann;
}
}
return null;
}
/**
* Returns <code>true</code> if method is annotated with one of provided annotation.
*/
public boolean hasAnnotation(MethodInfo methodInfo, Class<? extends Annotation>... an) {
AnnotationInfo[] anns = methodInfo.getAnnotations();
if (anns == null) {
return false;
}
for (Class<? extends Annotation> annotationClass : an) {
String anName = annotationClass.getName();
for (AnnotationInfo ann : anns) {
if (ann.getAnnotationClassname().equals(anName)) {
return true;
}
}
}
return false;
}
/**
* Finds annotation in class info. Returns <code>null</code> if annotation doesn't exist.
*/
public AnnotationInfo getAnnotation(ClassInfo classInfo, Class<? extends Annotation> an) {
AnnotationInfo[] anns = classInfo.getAnnotations();
if (anns == null) {
return null;
}
String anName = an.getName();
for (AnnotationInfo ann : anns) {
if (ann.getAnnotationClassname().equals(anName)) {
return ann;
}
}
return null;
}
/**
* Returns <code>true</code> if class is annotated with one of provided annotation.
*/
public boolean hasAnnotation(ClassInfo classInfo, Class<? extends Annotation>... an) {
AnnotationInfo[] anns = classInfo.getAnnotations();
if (anns == null) {
return false;
}
for (Class<? extends Annotation> annotationClass : an) {
String anName = annotationClass.getName();
for (AnnotationInfo ann : anns) {
if (ann.getAnnotationClassname().equals(anName)) {
return true;
}
}
}
return false;
}
/**
* Returns <code>true</code> if method has no arguments.
*/
public boolean hasNoArguments(MethodInfo methodInfo) {
return methodInfo.getArgumentsCount() == 0;
}
/**
* Returns <code>true</code> if method has only one argument.
*/
public boolean hasOneArgument(MethodInfo methodInfo) {
return methodInfo.getArgumentsCount() == 1;
}
// ---------------------------------------------------------------- methods level
/**
* Returns <code>true</code> if method is a top-level method.
*/
public boolean isTopLevelMethod(MethodInfo methodInfo) {
return methodInfo.isTopLevelMethod();
}
/**
* Returns <code>true</code> if method is declared in <code>Object</code> class (root class).
*/
public boolean isRootMethod(MethodInfo methodInfo) {
return AsmUtil.SIGNATURE_JAVA_LANG_OBJECT.equals(methodInfo.getDeclaredClassName());
}
/**
* Returns <code>true</code> if method is constructor or static block.
*/
public boolean isSpecialMethod(MethodInfo methodInfo) {
return
methodInfo.getMethodName().equals(ProxettaAsmUtil.INIT) ||
methodInfo.getMethodName().equals(ProxettaAsmUtil.CLINIT);
}
// ---------------------------------------------------------------- wildcards
/**
* Match method name to provided {@link jodd.util.Wildcard} pattern.
*/
public boolean matchMethodName(MethodInfo methodInfo, String wildcard) {
return Wildcard.match(methodInfo.getMethodName(), wildcard);
}
/**
* Match class name to provided {@link jodd.util.Wildcard} pattern.
*/
public boolean matchClassName(MethodInfo methodInfo, String wildcard) {
return Wildcard.match(methodInfo.getClassname(), wildcard);
}
// ---------------------------------------------------------------- return
/**
* Returns <code>true</code> if method's return type is <code>void</code>.
*/
public boolean hasNoReturnValue(MethodInfo methodInfo) {
return methodInfo.getReturnOpcodeType() == AsmUtil.TYPE_VOID;
}
/**
* Returns <code>true</code> if method has a return type.
*/
public boolean hasReturnValue(MethodInfo methodInfo) {
return methodInfo.getReturnOpcodeType() != AsmUtil.TYPE_VOID;
}
// ---------------------------------------------------------------- logical joins
/**
* Returns <code>true</code> if both pointcuts can be applied on the method..
*/
public boolean and(MethodInfo methodInfo, ProxyPointcut p1, ProxyPointcut p2) {
return p1.apply(methodInfo) && p2.apply(methodInfo);
}
/**
* Returns <code>true</code> if at least one pointcuts can be applied on the method..
*/
public boolean or(MethodInfo methodInfo, ProxyPointcut p1, ProxyPointcut p2) {
return p1.apply(methodInfo) || p2.apply(methodInfo);
}
}